20231129 webauthn attestation (#2351)

This adds full support for attestation of webauthn/passkeys.
This commit is contained in:
Firstyear 2023-12-03 16:13:52 +10:00 committed by GitHub
parent 85022e5e8a
commit 76269f9de2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 2815 additions and 921 deletions

22
Cargo.lock generated
View file

@ -459,7 +459,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "base64urlsafedata"
version = "0.1.3"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=2218d2055c0c900ef57b398423eee5e8d5521f4c#2218d2055c0c900ef57b398423eee5e8d5521f4c"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=5f4db4172f8e22aedc68c282d177e98db2b1892f#5f4db4172f8e22aedc68c282d177e98db2b1892f"
dependencies = [
"base64 0.21.5",
"paste 1.0.14",
@ -2830,9 +2830,9 @@ dependencies = [
[[package]]
name = "implicit-clone"
version = "0.3.6"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c6ecbd987bb94f1f3c76c6787879756cf4b6f73bfff48d79308e8c56b46f65f"
checksum = "cfd6201e7c30ccb24773cac7efa6fec1e06189d414b7439ce756a481c8bfbf53"
dependencies = [
"indexmap 1.9.3",
]
@ -5550,7 +5550,7 @@ checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a"
[[package]]
name = "sshkey-attest"
version = "0.5.0-dev"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=2218d2055c0c900ef57b398423eee5e8d5521f4c#2218d2055c0c900ef57b398423eee5e8d5521f4c"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=5f4db4172f8e22aedc68c282d177e98db2b1892f#5f4db4172f8e22aedc68c282d177e98db2b1892f"
dependencies = [
"base64urlsafedata",
"nom",
@ -6466,9 +6466,9 @@ dependencies = [
[[package]]
name = "web-sys"
version = "0.3.65"
version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85"
checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f"
dependencies = [
"js-sys",
"wasm-bindgen",
@ -6477,7 +6477,7 @@ dependencies = [
[[package]]
name = "webauthn-attestation-ca"
version = "0.1.0"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=2218d2055c0c900ef57b398423eee5e8d5521f4c#2218d2055c0c900ef57b398423eee5e8d5521f4c"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=5f4db4172f8e22aedc68c282d177e98db2b1892f#5f4db4172f8e22aedc68c282d177e98db2b1892f"
dependencies = [
"base64urlsafedata",
"openssl",
@ -6489,7 +6489,7 @@ dependencies = [
[[package]]
name = "webauthn-authenticator-rs"
version = "0.5.0-dev"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=2218d2055c0c900ef57b398423eee5e8d5521f4c#2218d2055c0c900ef57b398423eee5e8d5521f4c"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=5f4db4172f8e22aedc68c282d177e98db2b1892f#5f4db4172f8e22aedc68c282d177e98db2b1892f"
dependencies = [
"async-stream",
"async-trait",
@ -6521,7 +6521,7 @@ dependencies = [
[[package]]
name = "webauthn-rs"
version = "0.5.0-dev"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=2218d2055c0c900ef57b398423eee5e8d5521f4c#2218d2055c0c900ef57b398423eee5e8d5521f4c"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=5f4db4172f8e22aedc68c282d177e98db2b1892f#5f4db4172f8e22aedc68c282d177e98db2b1892f"
dependencies = [
"base64urlsafedata",
"serde",
@ -6534,7 +6534,7 @@ dependencies = [
[[package]]
name = "webauthn-rs-core"
version = "0.5.0-dev"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=2218d2055c0c900ef57b398423eee5e8d5521f4c#2218d2055c0c900ef57b398423eee5e8d5521f4c"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=5f4db4172f8e22aedc68c282d177e98db2b1892f#5f4db4172f8e22aedc68c282d177e98db2b1892f"
dependencies = [
"base64 0.21.5",
"base64urlsafedata",
@ -6558,7 +6558,7 @@ dependencies = [
[[package]]
name = "webauthn-rs-proto"
version = "0.5.0-dev"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=2218d2055c0c900ef57b398423eee5e8d5521f4c#2218d2055c0c900ef57b398423eee5e8d5521f4c"
source = "git+https://github.com/kanidm/webauthn-rs.git?rev=5f4db4172f8e22aedc68c282d177e98db2b1892f#5f4db4172f8e22aedc68c282d177e98db2b1892f"
dependencies = [
"base64urlsafedata",
"js-sys",

View file

@ -61,12 +61,12 @@ repository = "https://github.com/kanidm/kanidm/"
# scim_proto = { path = "../scim/proto" }
# scim_proto = { git = "https://github.com/kanidm/scim.git" }
base64urlsafedata = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "2218d2055c0c900ef57b398423eee5e8d5521f4c" }
webauthn-authenticator-rs = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "2218d2055c0c900ef57b398423eee5e8d5521f4c" }
webauthn-rs = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "2218d2055c0c900ef57b398423eee5e8d5521f4c" }
webauthn-rs-core = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "2218d2055c0c900ef57b398423eee5e8d5521f4c" }
webauthn-rs-proto = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "2218d2055c0c900ef57b398423eee5e8d5521f4c" }
sshkey-attest = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "2218d2055c0c900ef57b398423eee5e8d5521f4c" }
base64urlsafedata = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "5f4db4172f8e22aedc68c282d177e98db2b1892f" }
webauthn-authenticator-rs = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "5f4db4172f8e22aedc68c282d177e98db2b1892f" }
webauthn-rs = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "5f4db4172f8e22aedc68c282d177e98db2b1892f" }
webauthn-rs-core = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "5f4db4172f8e22aedc68c282d177e98db2b1892f" }
webauthn-rs-proto = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "5f4db4172f8e22aedc68c282d177e98db2b1892f" }
sshkey-attest = { git = "https://github.com/kanidm/webauthn-rs.git", rev = "5f4db4172f8e22aedc68c282d177e98db2b1892f" }
# base64urlsafedata = { path = "../webauthn-rs/base64urlsafedata" }
# webauthn-authenticator-rs = { path = "../webauthn-rs/webauthn-authenticator-rs" }

View file

@ -56,4 +56,16 @@ impl KanidmClient {
)
.await
}
pub async fn group_account_policy_webauthn_attestation_set(
&self,
id: &str,
att_ca_list: &str,
) -> Result<(), ClientError> {
self.perform_put_request(
&format!("/v1/group/{}/_attr/webauthn_attestation_ca_list", id),
vec![att_ca_list.to_string()],
)
.await
}
}

View file

@ -1784,6 +1784,36 @@ impl KanidmClient {
.await
}
pub async fn idm_account_credential_update_attested_passkey_init(
&self,
session_token: &CUSessionToken,
) -> Result<CUStatus, ClientError> {
let scr = CURequest::AttestedPasskeyInit;
self.perform_simple_post_request("/v1/credential/_update", &(scr, &session_token))
.await
}
pub async fn idm_account_credential_update_attested_passkey_finish(
&self,
session_token: &CUSessionToken,
label: String,
registration: RegisterPublicKeyCredential,
) -> Result<CUStatus, ClientError> {
let scr = CURequest::AttestedPasskeyFinish(label, registration);
self.perform_simple_post_request("/v1/credential/_update", &(scr, &session_token))
.await
}
pub async fn idm_account_credential_update_attested_passkey_remove(
&self,
session_token: &CUSessionToken,
uuid: Uuid,
) -> Result<CUStatus, ClientError> {
let scr = CURequest::AttestedPasskeyRemove(uuid);
self.perform_simple_post_request("/v1/credential/_update", &(scr, &session_token))
.await
}
pub async fn idm_account_credential_update_commit(
&self,
session_token: &CUSessionToken,

View file

@ -52,6 +52,7 @@ pub const ATTR_ACP_RECEIVER: &str = "acp_receiver";
pub const ATTR_ACP_SEARCH_ATTR: &str = "acp_search_attr";
pub const ATTR_ACP_TARGET_SCOPE: &str = "acp_targetscope";
pub const ATTR_API_TOKEN_SESSION: &str = "api_token_session";
pub const ATTR_ATTESTED_PASSKEYS: &str = "attested_passkeys";
pub const ATTR_ATTR: &str = "attr";
pub const ATTR_ATTRIBUTENAME: &str = "attributename";
pub const ATTR_ATTRIBUTETYPE: &str = "attributetype";
@ -67,7 +68,6 @@ pub const ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: &str = "credential_update_intent_
pub const ATTR_CREDENTIAL_TYPE_MINIMUM: &str = "credential_type_minimum";
pub const ATTR_DENIED_NAME: &str = "denied_name";
pub const ATTR_DESCRIPTION: &str = "description";
pub const ATTR_DEVICEKEYS: &str = "devicekeys";
pub const ATTR_DIRECTMEMBEROF: &str = "directmemberof";
pub const ATTR_DISPLAYNAME: &str = "displayname";
pub const ATTR_DN: &str = "dn";
@ -176,6 +176,7 @@ pub const ATTR_USERID: &str = "userid";
pub const ATTR_USERPASSWORD: &str = "userpassword";
pub const ATTR_UUID: &str = "uuid";
pub const ATTR_VERSION: &str = "version";
pub const ATTR_WEBAUTHN_ATTESTATION_CA_LIST: &str = "webauthn_attestation_ca_list";
pub const OAUTH2_SCOPE_EMAIL: &str = ATTR_EMAIL;
pub const OAUTH2_SCOPE_GROUPS: &str = "groups";

View file

@ -289,6 +289,9 @@ pub enum OperationError {
/// When a name is denied by the system config
ValueDenyName,
// What about something like this for unique errors?
// Credential Update Errors
CU0001WebauthnAttestationNotTrusted,
CU0002WebauthnRegistrationError,
// ValueSet errors
VS0001IncomingReplSshPublicKey,
// Value Errors
@ -1161,6 +1164,9 @@ pub enum CURequest {
PasskeyInit,
PasskeyFinish(String, RegisterPublicKeyCredential),
PasskeyRemove(Uuid),
AttestedPasskeyInit,
AttestedPasskeyFinish(String, RegisterPublicKeyCredential),
AttestedPasskeyRemove(Uuid),
}
impl fmt::Debug for CURequest {
@ -1178,6 +1184,9 @@ impl fmt::Debug for CURequest {
CURequest::PasskeyInit => "CURequest::PasskeyInit",
CURequest::PasskeyFinish(_, _) => "CURequest::PasskeyFinish",
CURequest::PasskeyRemove(_) => "CURequest::PasskeyRemove",
CURequest::AttestedPasskeyInit => "CURequest::AttestedPasskeyInit",
CURequest::AttestedPasskeyFinish(_, _) => "CURequest::AttestedPasskeyFinish",
CURequest::AttestedPasskeyRemove(_) => "CURequest::AttestedPasskeyRemove",
};
writeln!(f, "{}", t)
}
@ -1192,6 +1201,7 @@ pub enum CURegState {
TotpInvalidSha1,
BackupCodes(Vec<String>),
Passkey(CreationChallengeResponse),
AttestedPasskey(CreationChallengeResponse),
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
@ -1201,9 +1211,10 @@ pub enum CUExtPortal {
Some(Url),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema, PartialEq)]
pub enum CUCredState {
Modifiable,
DeleteOnly,
AccessDeny,
PolicyDeny,
// Disabled,
@ -1213,7 +1224,10 @@ pub enum CUCredState {
pub enum CURegWarning {
MfaRequired,
PasskeyRequired,
AttestedPasskeyRequired,
AttestedResidentKeyRequired,
Unsatisfiable,
WebauthnAttestationUnsatisfiable,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
@ -1231,6 +1245,9 @@ pub struct CUStatus {
pub primary_state: CUCredState,
pub passkeys: Vec<PasskeyDetail>,
pub passkeys_state: CUCredState,
pub attested_passkeys: Vec<PasskeyDetail>,
pub attested_passkeys_state: CUCredState,
pub attested_passkeys_allowed_devices: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, ToSchema)]

View file

@ -1251,7 +1251,7 @@ impl QueryServerReadV1 {
.map_err(|e| {
admin_error!(
err = ?e,
"Failed to begin credential_passkey_init",
"Failed to begin credential_passkey_finish",
);
e
}),
@ -1260,7 +1260,34 @@ impl QueryServerReadV1 {
.map_err(|e| {
admin_error!(
err = ?e,
"Failed to begin credential_passkey_init",
"Failed to begin credential_passkey_remove",
);
e
}),
CURequest::AttestedPasskeyInit => idms_cred_update
.credential_attested_passkey_init(&session_token, ct)
.map_err(|e| {
admin_error!(
err = ?e,
"Failed to begin credential_attested_passkey_init",
);
e
}),
CURequest::AttestedPasskeyFinish(label, rpkc) => idms_cred_update
.credential_attested_passkey_finish(&session_token, ct, label, &rpkc)
.map_err(|e| {
admin_error!(
err = ?e,
"Failed to begin credential_attested_passkey_finish",
);
e
}),
CURequest::AttestedPasskeyRemove(uuid) => idms_cred_update
.credential_attested_passkey_remove(&session_token, ct, uuid)
.map_err(|e| {
admin_error!(
err = ?e,
"Failed to begin credential_attested_passkey_remove",
);
e
}),

View file

@ -8,7 +8,8 @@ use serde_with::skip_serializing_none;
use url::Url;
use uuid::Uuid;
use webauthn_rs::prelude::{
AttestedPasskey as DeviceKeyV4, Passkey as PasskeyV4, SecurityKey as SecurityKeyV4,
AttestationCaList, AttestedPasskey as AttestedPasskeyV4, Passkey as PasskeyV4,
SecurityKey as SecurityKeyV4,
};
use webauthn_rs_core::proto::{COSEKey, UserVerificationPolicy};
@ -60,6 +61,8 @@ pub enum DbValueIntentTokenStateV1 {
#[serde(default)]
passkeys_can_edit: bool,
#[serde(default)]
attested_passkeys_can_edit: bool,
#[serde(default)]
unixcred_can_edit: bool,
#[serde(default)]
sshpubkey_can_edit: bool,
@ -76,6 +79,8 @@ pub enum DbValueIntentTokenStateV1 {
#[serde(default)]
passkeys_can_edit: bool,
#[serde(default)]
attested_passkeys_can_edit: bool,
#[serde(default)]
unixcred_can_edit: bool,
#[serde(default)]
sshpubkey_can_edit: bool,
@ -347,8 +352,12 @@ pub enum DbValuePasskeyV1 {
}
#[derive(Serialize, Deserialize, Debug)]
pub enum DbValueDeviceKeyV1 {
V4 { u: Uuid, t: String, k: DeviceKeyV4 },
pub enum DbValueAttestedPasskeyV1 {
V4 {
u: Uuid,
t: String,
k: AttestedPasskeyV4,
},
}
#[derive(Serialize, Deserialize, Debug)]
@ -674,7 +683,7 @@ pub enum DbValueSetV2 {
#[serde(rename = "PK")]
Passkey(Vec<DbValuePasskeyV1>),
#[serde(rename = "DK")]
DeviceKey(Vec<DbValueDeviceKeyV1>),
AttestedPasskey(Vec<DbValueAttestedPasskeyV1>),
#[serde(rename = "TE")]
TrustedDeviceEnrollment(Vec<Uuid>),
#[serde(rename = "AS")]
@ -699,6 +708,8 @@ pub enum DbValueSetV2 {
Image(Vec<DbValueImage>),
#[serde(rename = "CT")]
CredentialType(Vec<u16>),
#[serde(rename = "WC")]
WebauthnAttestationCaList { ca_list: AttestationCaList },
}
impl DbValueSetV2 {
@ -732,7 +743,7 @@ impl DbValueSetV2 {
DbValueSetV2::RestrictedString(set) => set.len(),
DbValueSetV2::IntentToken(set) => set.len(),
DbValueSetV2::Passkey(set) => set.len(),
DbValueSetV2::DeviceKey(set) => set.len(),
DbValueSetV2::AttestedPasskey(set) => set.len(),
DbValueSetV2::TrustedDeviceEnrollment(set) => set.len(),
DbValueSetV2::Session(set) => set.len(),
DbValueSetV2::ApiToken(set) => set.len(),
@ -746,6 +757,7 @@ impl DbValueSetV2 {
DbValueSetV2::EcKeyPrivate(_key) => 1, // here we have to hard code it because the Vec<u8>
// represents the bytes of SINGLE(!) key
DbValueSetV2::CredentialType(set) => set.len(),
DbValueSetV2::WebauthnAttestationCaList { ca_list } => ca_list.len(),
}
}

View file

@ -208,7 +208,7 @@ lazy_static! {
Attribute::PrimaryCredential,
Attribute::UserAuthTokenSession,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
],
..Default::default()
};
@ -241,7 +241,7 @@ lazy_static! {
Attribute::SshPublicKey,
Attribute::UnixPassword,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
Attribute::UserAuthTokenSession,
],
modify_present_attrs: vec![
@ -253,7 +253,7 @@ lazy_static! {
Attribute::SshPublicKey,
Attribute::UnixPassword,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
],
..Default::default()
};
@ -442,7 +442,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
],
create_classes: vec![EntryClass::Object, EntryClass::Account, EntryClass::Person,],
..Default::default()
@ -695,7 +695,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
Attribute::ApiTokenSession,
Attribute::UserAuthTokenSession,
],
@ -729,7 +729,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
Attribute::ApiTokenSession,
Attribute::UserAuthTokenSession,
Attribute::IdVerificationEcKey,
@ -743,7 +743,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
Attribute::ApiTokenSession,
],
..Default::default()
@ -779,7 +779,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
],
create_classes: vec![
EntryClass::Object,
@ -895,7 +895,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
Attribute::ApiTokenSession,
Attribute::UserAuthTokenSession,
],
@ -925,7 +925,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
Attribute::ApiTokenSession,
Attribute::UserAuthTokenSession,
Attribute::IdVerificationEcKey,
@ -938,7 +938,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
Attribute::ApiTokenSession,
],
..Default::default()
@ -1275,6 +1275,7 @@ lazy_static! {
Attribute::AuthPasswordMinimumLength,
Attribute::CredentialTypeMinimum,
Attribute::PrivilegeExpiry,
Attribute::WebauthnAttestationCaList,
],
modify_removed_attrs: vec![
Attribute::Class,
@ -1282,6 +1283,7 @@ lazy_static! {
Attribute::AuthPasswordMinimumLength,
Attribute::CredentialTypeMinimum,
Attribute::PrivilegeExpiry,
Attribute::WebauthnAttestationCaList,
],
modify_present_attrs: vec![
Attribute::Class,
@ -1289,6 +1291,7 @@ lazy_static! {
Attribute::AuthPasswordMinimumLength,
Attribute::CredentialTypeMinimum,
Attribute::PrivilegeExpiry,
Attribute::WebauthnAttestationCaList,
],
modify_classes: vec![
EntryClass::AccountPolicy,
@ -1329,7 +1332,7 @@ lazy_static! {
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::PassKeys,
Attribute::DeviceKeys,
Attribute::AttestedPasskeys,
],
create_classes: vec![
EntryClass::Object,

View file

@ -50,6 +50,7 @@ pub enum Attribute {
AcpSearchAttr,
AcpTargetScope,
ApiTokenSession,
AttestedPasskeys,
Attr,
AttributeName,
AttributeType,
@ -65,7 +66,6 @@ pub enum Attribute {
CredentialTypeMinimum,
DeniedName,
Description,
DeviceKeys,
DirectMemberOf,
DisplayName,
Dn,
@ -173,6 +173,7 @@ pub enum Attribute {
UserPassword,
Uuid,
Version,
WebauthnAttestationCaList,
#[cfg(any(debug_assertions, test))]
NonExist,
@ -232,6 +233,7 @@ impl TryFrom<String> for Attribute {
ATTR_ACP_SEARCH_ATTR => Attribute::AcpSearchAttr,
ATTR_ACP_TARGET_SCOPE => Attribute::AcpTargetScope,
ATTR_API_TOKEN_SESSION => Attribute::ApiTokenSession,
ATTR_ATTESTED_PASSKEYS => Attribute::AttestedPasskeys,
ATTR_ATTR => Attribute::Attr,
ATTR_ATTRIBUTENAME => Attribute::AttributeName,
ATTR_ATTRIBUTETYPE => Attribute::AttributeType,
@ -247,7 +249,6 @@ impl TryFrom<String> for Attribute {
ATTR_CREDENTIAL_TYPE_MINIMUM => Attribute::CredentialTypeMinimum,
ATTR_DENIED_NAME => Attribute::DeniedName,
ATTR_DESCRIPTION => Attribute::Description,
ATTR_DEVICEKEYS => Attribute::DeviceKeys,
ATTR_DIRECTMEMBEROF => Attribute::DirectMemberOf,
ATTR_DISPLAYNAME => Attribute::DisplayName,
ATTR_DN => Attribute::Dn,
@ -353,6 +354,7 @@ impl TryFrom<String> for Attribute {
ATTR_USERPASSWORD => Attribute::UserPassword,
ATTR_UUID => Attribute::Uuid,
ATTR_VERSION => Attribute::Version,
ATTR_WEBAUTHN_ATTESTATION_CA_LIST => Attribute::WebauthnAttestationCaList,
#[cfg(any(debug_assertions, test))]
TEST_ATTR_NON_EXIST => Attribute::NonExist,
@ -390,6 +392,7 @@ impl From<Attribute> for &'static str {
Attribute::AcpSearchAttr => ATTR_ACP_SEARCH_ATTR,
Attribute::AcpTargetScope => ATTR_ACP_TARGET_SCOPE,
Attribute::ApiTokenSession => ATTR_API_TOKEN_SESSION,
Attribute::AttestedPasskeys => ATTR_ATTESTED_PASSKEYS,
Attribute::Attr => ATTR_ATTR,
Attribute::AttributeName => ATTR_ATTRIBUTENAME,
Attribute::AttributeType => ATTR_ATTRIBUTETYPE,
@ -405,7 +408,6 @@ impl From<Attribute> for &'static str {
Attribute::CredentialTypeMinimum => ATTR_CREDENTIAL_TYPE_MINIMUM,
Attribute::DeniedName => ATTR_DENIED_NAME,
Attribute::Description => ATTR_DESCRIPTION,
Attribute::DeviceKeys => ATTR_DEVICEKEYS,
Attribute::DirectMemberOf => ATTR_DIRECTMEMBEROF,
Attribute::DisplayName => ATTR_DISPLAYNAME,
Attribute::Dn => ATTR_DN,
@ -511,6 +513,7 @@ impl From<Attribute> for &'static str {
Attribute::UserPassword => ATTR_USERPASSWORD,
Attribute::Uuid => ATTR_UUID,
Attribute::Version => ATTR_VERSION,
Attribute::WebauthnAttestationCaList => ATTR_WEBAUTHN_ATTESTATION_CA_LIST,
#[cfg(any(debug_assertions, test))]
Attribute::NonExist => TEST_ATTR_NON_EXIST,

View file

@ -251,7 +251,7 @@ pub static ref SCHEMA_ATTR_LOGINSHELL: SchemaAttribute = SchemaAttribute {
pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD,
name: Attribute::UnixPassword.into(),
description: "A POSIX user's UNIX login password.to_string().".to_string(),
description: "A POSIX user's UNIX login password.".to_string(),
index: vec![IndexType::Presence],
syntax: SyntaxType::Credential,
@ -273,7 +273,7 @@ pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute {
pub static ref SCHEMA_ATTR_ACCOUNT_EXPIRE: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_ACCOUNT_EXPIRE,
name: Attribute::AccountExpire.into(),
description: "The datetime after which this account no longer may authenticate.to_string().".to_string(),
description: "The datetime after which this account no longer may authenticate.".to_string(),
sync_allowed: true,
syntax: SyntaxType::DateTime,
@ -283,13 +283,22 @@ pub static ref SCHEMA_ATTR_ACCOUNT_EXPIRE: SchemaAttribute = SchemaAttribute {
pub static ref SCHEMA_ATTR_ACCOUNT_VALID_FROM: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_ACCOUNT_VALID_FROM,
name: Attribute::AccountValidFrom.into(),
description: "The datetime after which this account may commence authenticating.to_string().".to_string(),
description: "The datetime after which this account may commence authenticating.".to_string(),
sync_allowed: true,
syntax: SyntaxType::DateTime,
..Default::default()
};
pub static ref SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST,
name: Attribute::WebauthnAttestationCaList.into(),
description: "A set of CA's that limit devices that can be used with webauthn.".to_string(),
syntax: SyntaxType::WebauthnAttestationCaList,
multivalue: true,
..Default::default()
};
pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME,
name: Attribute::OAuth2RsName.into(),
@ -461,15 +470,15 @@ pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute {
..Default::default()
};
pub static ref SCHEMA_ATTR_DEVICEKEYS: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DEVICEKEYS,
name: Attribute::DeviceKeys.into(),
pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS,
name: Attribute::AttestedPasskeys.into(),
description: "A set of registered device keys".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::DeviceKey,
syntax: SyntaxType::AttestedPasskey,
..Default::default()
};
@ -657,7 +666,8 @@ pub static ref SCHEMA_CLASS_ACCOUNT_POLICY: SchemaClass = SchemaClass {
Attribute::AuthSessionExpiry.into(),
Attribute::PrivilegeExpiry.into(),
Attribute::AuthPasswordMinimumLength.into(),
Attribute::CredentialTypeMinimum.into()
Attribute::CredentialTypeMinimum.into(),
Attribute::WebauthnAttestationCaList.into(),
],
systemsupplements: vec![Attribute::Group.into()],
..Default::default()
@ -672,7 +682,7 @@ pub static ref SCHEMA_CLASS_ACCOUNT: SchemaClass = SchemaClass {
systemmay: vec![
Attribute::PrimaryCredential.into(),
Attribute::PassKeys.into(),
Attribute::DeviceKeys.into(),
Attribute::AttestedPasskeys.into(),
Attribute::CredentialUpdateIntentToken.into(),
Attribute::SshPublicKey.into(),
Attribute::RadiusSecret.into(),

View file

@ -184,7 +184,7 @@ pub const UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: Uuid =
pub const UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: Uuid =
uuid!("00000000-0000-0000-0000-ffff00000098");
pub const UUID_SCHEMA_ATTR_PASSKEYS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000099");
pub const UUID_SCHEMA_ATTR_DEVICEKEYS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000100");
pub const UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000100");
pub const UUID_SCHEMA_ATTR_SYSTEMSUPPLEMENTS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000101");
pub const UUID_SCHEMA_ATTR_SUPPLEMENTS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000102");
@ -252,6 +252,8 @@ pub const UUID_SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM: Uuid =
pub const UUID_SCHEMA_ATTR_SUDOHOST: Uuid = uuid!("00000000-0000-0000-0000-ffff00000149");
pub const UUID_SCHEMA_ATTR_UID: Uuid = uuid!("00000000-0000-0000-0000-ffff00000150");
pub const UUID_SCHEMA_ATTR_GECOS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000151");
pub const UUID_SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST: Uuid =
uuid!("00000000-0000-0000-0000-ffff00000152");
// System and domain infos
// I'd like to strongly criticise william of the past for making poor choices about these allocations.

View file

@ -43,7 +43,9 @@ use smartstring::alias::String as AttrString;
use time::OffsetDateTime;
use tracing::trace;
use uuid::Uuid;
use webauthn_rs::prelude::{AttestedPasskey as DeviceKeyV4, Passkey as PasskeyV4};
use webauthn_rs::prelude::{
AttestationCaList, AttestedPasskey as AttestedPasskeyV4, Passkey as PasskeyV4,
};
use crate::be::dbentry::{DbEntry, DbEntryVers};
use crate::be::dbvalue::DbValueSetV2;
@ -2733,13 +2735,13 @@ impl<VALID, STATE> Entry<VALID, STATE> {
#[inline(always)]
/// Get the set of devicekeys on this account, if any are present.
pub fn get_ava_devicekeys(
pub fn get_ava_attestedpasskeys(
&self,
attr: Attribute,
) -> Option<&BTreeMap<Uuid, (String, DeviceKeyV4)>> {
) -> Option<&BTreeMap<Uuid, (String, AttestedPasskeyV4)>> {
self.attrs
.get(attr.as_ref())
.and_then(|vs| vs.as_devicekey_map())
.and_then(|vs| vs.as_attestedpasskey_map())
}
#[inline(always)]
@ -2851,6 +2853,16 @@ impl<VALID, STATE> Entry<VALID, STATE> {
.get(attr.as_ref())
.and_then(|vs| vs.to_eckey_public_single())
}
pub fn get_ava_webauthn_attestation_ca_list(
&self,
attr: Attribute,
) -> Option<&AttestationCaList> {
self.attrs
.get(attr.as_ref())
.and_then(|vs| vs.as_webauthn_attestation_ca_list())
}
#[inline(always)]
/// Return a single security principle name, if valid to transform this value.
pub(crate) fn generate_spn(&self, domain_name: &str) -> Option<Value> {

View file

@ -8,7 +8,7 @@ use kanidm_proto::v1::{
use time::OffsetDateTime;
use uuid::Uuid;
use webauthn_rs::prelude::{
AttestedPasskey as DeviceKeyV4, AuthenticationResult, CredentialID, Passkey as PasskeyV4,
AttestedPasskey as AttestedPasskeyV4, AuthenticationResult, CredentialID, Passkey as PasskeyV4,
};
use super::accountpolicy::ResolvedAccountPolicy;
@ -57,7 +57,7 @@ pub struct Account {
pub groups: Vec<Group>,
pub primary: Option<Credential>,
pub passkeys: BTreeMap<Uuid, (String, PasskeyV4)>,
pub devicekeys: BTreeMap<Uuid, (String, DeviceKeyV4)>,
pub attested_passkeys: BTreeMap<Uuid, (String, AttestedPasskeyV4)>,
pub valid_from: Option<OffsetDateTime>,
pub expire: Option<OffsetDateTime>,
pub radius_secret: Option<String>,
@ -106,8 +106,8 @@ macro_rules! try_from_entry {
.cloned()
.unwrap_or_default();
let devicekeys = $value
.get_ava_devicekeys(Attribute::DeviceKeys)
let attested_passkeys = $value
.get_ava_attestedpasskeys(Attribute::AttestedPasskeys)
.cloned()
.unwrap_or_default();
@ -206,7 +206,7 @@ macro_rules! try_from_entry {
groups,
primary,
passkeys,
devicekeys,
attested_passkeys,
valid_from,
expire,
radius_secret,
@ -522,6 +522,21 @@ impl Account {
}
});
// Is it an attested passkey?
self.attested_passkeys.iter_mut().for_each(|(u, (t, k))| {
if let Some(true) = k.update_credential(auth_result) {
ml.push(Modify::Removed(
Attribute::AttestedPasskeys.into(),
PartialValue::AttestedPasskey(*u),
));
ml.push(Modify::Present(
Attribute::AttestedPasskeys.into(),
Value::AttestedPasskey(*u, t.clone(), k.clone()),
));
}
});
if ml.is_empty() {
Ok(None)
} else {
@ -641,6 +656,8 @@ impl Account {
true
}
(SessionState::RevokedAt(_), _) => {
// William, if you have added a new type of credential, and end up here, you
// need to look at session consistency plugin.
security_info!("Session has been revoked");
false
}

View file

@ -1,5 +1,6 @@
use crate::prelude::*;
use crate::value::CredentialType;
use webauthn_rs::prelude::AttestationCaList;
// use crate::idm::server::IdmServerProxyWriteTransaction;
#[derive(Clone)]
@ -8,6 +9,7 @@ pub(crate) struct AccountPolicy {
authsession_expiry: u32,
pw_min_length: u32,
credential_policy: CredentialType,
webauthn_att_ca_list: Option<AttestationCaList>,
}
impl From<&EntrySealedCommitted> for Option<AccountPolicy> {
@ -22,9 +24,11 @@ impl From<&EntrySealedCommitted> for Option<AccountPolicy> {
let authsession_expiry = val
.get_ava_single_uint32(Attribute::AuthSessionExpiry)
.unwrap_or(MAXIMUM_AUTH_SESSION_EXPIRY);
let privilege_expiry = val
.get_ava_single_uint32(Attribute::PrivilegeExpiry)
.unwrap_or(MAXIMUM_AUTH_PRIVILEGE_EXPIRY);
let pw_min_length = val
.get_ava_single_uint32(Attribute::AuthPasswordMinimumLength)
.unwrap_or(PW_MIN_LENGTH);
@ -33,11 +37,16 @@ impl From<&EntrySealedCommitted> for Option<AccountPolicy> {
.get_ava_single_credential_type(Attribute::CredentialTypeMinimum)
.unwrap_or(CredentialType::Any);
let webauthn_att_ca_list = val
.get_ava_webauthn_attestation_ca_list(Attribute::WebauthnAttestationCaList)
.cloned();
Some(AccountPolicy {
privilege_expiry,
authsession_expiry,
pw_min_length,
credential_policy,
webauthn_att_ca_list,
})
}
}
@ -49,6 +58,7 @@ pub(crate) struct ResolvedAccountPolicy {
authsession_expiry: u32,
pw_min_length: u32,
credential_policy: CredentialType,
webauthn_att_ca_list: Option<AttestationCaList>,
}
impl ResolvedAccountPolicy {
@ -62,6 +72,7 @@ impl ResolvedAccountPolicy {
authsession_expiry: MAXIMUM_AUTH_SESSION_EXPIRY,
pw_min_length: PW_MIN_LENGTH,
credential_policy: CredentialType::Any,
webauthn_att_ca_list: None,
};
iter.for_each(|acc_pol| {
@ -84,6 +95,14 @@ impl ResolvedAccountPolicy {
if acc_pol.credential_policy > accumulate.credential_policy {
accumulate.credential_policy = acc_pol.credential_policy
}
if let Some(acc_pol_w_att_ca) = acc_pol.webauthn_att_ca_list {
if let Some(res_w_att_ca) = accumulate.webauthn_att_ca_list.as_mut() {
res_w_att_ca.intersection(&acc_pol_w_att_ca);
} else {
accumulate.webauthn_att_ca_list = Some(acc_pol_w_att_ca);
}
}
});
accumulate
@ -104,27 +123,107 @@ impl ResolvedAccountPolicy {
pub(crate) fn credential_policy(&self) -> CredentialType {
self.credential_policy
}
pub(crate) fn webauthn_attestation_ca_list(&self) -> Option<&AttestationCaList> {
self.webauthn_att_ca_list.as_ref()
}
}
#[cfg(test)]
mod tests {
use super::{AccountPolicy, CredentialType, ResolvedAccountPolicy};
// use crate::prelude::*;
use crate::prelude::*;
use webauthn_rs_core::proto::AttestationCaListBuilder;
#[test]
fn test_idm_account_policy_resolve() {
sketching::test_init();
// Yubico U2F Root CA Serial 457200631
let ca_root_a: &[u8] = b"-----BEGIN CERTIFICATE-----
MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ
dWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAw
MDBaGA8yMDUwMDkwNDAwMDAwMFowLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290
IENBIFNlcmlhbCA0NTcyMDA2MzEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC/jwYuhBVlqaiYWEMsrWFisgJ+PtM91eSrpI4TK7U53mwCIawSDHy8vUmk
5N2KAj9abvT9NP5SMS1hQi3usxoYGonXQgfO6ZXyUA9a+KAkqdFnBnlyugSeCOep
8EdZFfsaRFtMjkwz5Gcz2Py4vIYvCdMHPtwaz0bVuzneueIEz6TnQjE63Rdt2zbw
nebwTG5ZybeWSwbzy+BJ34ZHcUhPAY89yJQXuE0IzMZFcEBbPNRbWECRKgjq//qT
9nmDOFVlSRCt2wiqPSzluwn+v+suQEBsUjTGMEd25tKXXTkNW21wIWbxeSyUoTXw
LvGS6xlwQSgNpk2qXYwf8iXg7VWZAgMBAAGjQjBAMB0GA1UdDgQWBBQgIvz0bNGJ
hjgpToksyKpP9xv9oDAPBgNVHRMECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAN
BgkqhkiG9w0BAQsFAAOCAQEAjvjuOMDSa+JXFCLyBKsycXtBVZsJ4Ue3LbaEsPY4
MYN/hIQ5ZM5p7EjfcnMG4CtYkNsfNHc0AhBLdq45rnT87q/6O3vUEtNMafbhU6kt
hX7Y+9XFN9NpmYxr+ekVY5xOxi8h9JDIgoMP4VB1uS0aunL1IGqrNooL9mmFnL2k
LVVee6/VR6C5+KSTCMCWppMuJIZII2v9o4dkoZ8Y7QRjQlLfYzd3qGtKbw7xaF1U
sG/5xUb/Btwb2X2g4InpiB/yt/3CpQXpiWX/K4mBvUKiGn05ZsqeY1gx4g0xLBqc
U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw==
-----END CERTIFICATE-----";
// Defunct Apple WebAuthn Root CA
let ca_root_b: &[u8] = b"-----BEGIN CERTIFICATE-----
MIICEjCCAZmgAwIBAgIQaB0BbHo84wIlpQGUKEdXcTAKBggqhkjOPQQDAzBLMR8w
HQYDVQQDDBZBcHBsZSBXZWJBdXRobiBSb290IENBMRMwEQYDVQQKDApBcHBsZSBJ
bmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMB4XDTIwMDMxODE4MjEzMloXDTQ1MDMx
NTAwMDAwMFowSzEfMB0GA1UEAwwWQXBwbGUgV2ViQXV0aG4gUm9vdCBDQTETMBEG
A1UECgwKQXBwbGUgSW5jLjETMBEGA1UECAwKQ2FsaWZvcm5pYTB2MBAGByqGSM49
AgEGBSuBBAAiA2IABCJCQ2pTVhzjl4Wo6IhHtMSAzO2cv+H9DQKev3//fG59G11k
xu9eI0/7o6V5uShBpe1u6l6mS19S1FEh6yGljnZAJ+2GNP1mi/YK2kSXIuTHjxA/
pcoRf7XkOtO4o1qlcaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJtdk
2cV4wlpn0afeaxLQG2PxxtcwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA
MGQCMFrZ+9DsJ1PW9hfNdBywZDsWDbWFp28it1d/5w2RPkRX3Bbn/UbDTNLx7Jr3
jAGGiQIwHFj+dJZYUJR786osByBelJYsVZd2GbHQu209b5RCmGQ21gpSAk9QZW4B
1bWeT0vT
-----END CERTIFICATE-----";
let aaguid_a = Uuid::new_v4();
let aaguid_b = Uuid::new_v4();
let aaguid_c = Uuid::new_v4();
let aaguid_d = Uuid::new_v4();
let aaguid_e = Uuid::new_v4();
let mut att_ca_builder = AttestationCaListBuilder::new();
att_ca_builder
.insert_device_pem(ca_root_a, aaguid_a, "A".to_string(), Default::default())
.unwrap();
att_ca_builder
.insert_device_pem(ca_root_a, aaguid_b, "B".to_string(), Default::default())
.unwrap();
att_ca_builder
.insert_device_pem(ca_root_a, aaguid_c, "C".to_string(), Default::default())
.unwrap();
att_ca_builder
.insert_device_pem(ca_root_b, aaguid_d, "D".to_string(), Default::default())
.unwrap();
let att_ca_list_a = att_ca_builder.build();
let policy_a = AccountPolicy {
privilege_expiry: 100,
authsession_expiry: 100,
pw_min_length: 11,
credential_policy: CredentialType::Mfa,
webauthn_att_ca_list: Some(att_ca_list_a),
};
let mut att_ca_builder = AttestationCaListBuilder::new();
att_ca_builder
.insert_device_pem(ca_root_a, aaguid_b, "B".to_string(), Default::default())
.unwrap();
att_ca_builder
.insert_device_pem(ca_root_b, aaguid_e, "E".to_string(), Default::default())
.unwrap();
let att_ca_list_b = att_ca_builder.build();
let policy_b = AccountPolicy {
privilege_expiry: 150,
authsession_expiry: 50,
pw_min_length: 15,
credential_policy: CredentialType::Passkey,
webauthn_att_ca_list: Some(att_ca_list_b),
};
let rap = ResolvedAccountPolicy::fold_from([policy_a, policy_b].into_iter());
@ -133,15 +232,15 @@ mod tests {
assert_eq!(rap.authsession_expiry(), 50);
assert_eq!(rap.pw_min_length(), 15);
assert_eq!(rap.credential_policy, CredentialType::Passkey);
}
/*
#[idm_test]
async fn test_idm_account_policy_load(
idms: &IdmServer,
_idms_delayed: &mut IdmServerDelayed,
) {
todo!();
let mut att_ca_builder = AttestationCaListBuilder::new();
att_ca_builder
.insert_device_pem(ca_root_a, aaguid_b, "B".to_string(), Default::default())
.unwrap();
let att_ca_list_ex = att_ca_builder.build();
assert_eq!(rap.webauthn_att_ca_list, Some(att_ca_list_ex));
}
*/
}

View file

@ -15,10 +15,10 @@ use kanidm_proto::v1::{
use nonempty::{nonempty, NonEmpty};
use tokio::sync::mpsc::UnboundedSender as Sender;
use uuid::Uuid;
use webauthn_rs::prelude::Passkey as PasskeyV4;
use webauthn_rs::prelude::{
CredentialID, PasskeyAuthentication, RequestChallengeResponse, SecurityKeyAuthentication,
Webauthn,
AttestationCaList, AttestedPasskey as AttestedPasskeyV4, AttestedPasskeyAuthentication,
CredentialID, Passkey as PasskeyV4, PasskeyAuthentication, RequestChallengeResponse,
SecurityKeyAuthentication, Webauthn,
};
use crate::credential::totp::Totp;
@ -43,6 +43,7 @@ use super::accountpolicy::ResolvedAccountPolicy;
const BAD_PASSWORD_MSG: &str = "incorrect password";
const BAD_TOTP_MSG: &str = "incorrect totp";
const BAD_WEBAUTHN_MSG: &str = "invalid webauthn authentication";
const BAD_ACCOUNT_POLICY: &str = "the credential no longer meets account policy requirements";
const BAD_BACKUPCODE_MSG: &str = "invalid backup code";
const BAD_AUTH_TYPE_MSG: &str = "invalid authentication method in this context";
const BAD_CREDENTIALS: &str = "invalid credential message";
@ -56,6 +57,7 @@ pub enum AuthType {
GeneratedPassword,
PasswordMfa,
Passkey,
AttestedPasskey,
}
impl fmt::Display for AuthType {
@ -66,6 +68,7 @@ impl fmt::Display for AuthType {
AuthType::GeneratedPassword => write!(f, "generatedpassword"),
AuthType::PasswordMfa => write!(f, "passwordmfa"),
AuthType::Passkey => write!(f, "passkey"),
AuthType::AttestedPasskey => write!(f, "attested_passkey"),
}
}
}
@ -108,13 +111,21 @@ struct CredMfa {
}
#[derive(Clone, Debug)]
/// The state of a webauthn credential during authentication
struct CredWebauthn {
/// The state of a passkey during authentication
struct CredPasskey {
chal: RequestChallengeResponse,
wan_state: PasskeyAuthentication,
state: CredVerifyState,
}
#[derive(Clone, Debug)]
/// The state of an attested passkey during authentication
struct CredAttestedPasskey {
chal: RequestChallengeResponse,
wan_state: AttestedPasskeyAuthentication,
state: CredVerifyState,
}
/// The current active handler for this authentication session. This is determined from what credentials
/// are possible from the account, and what the user selected as the preferred authentication
/// mechanism.
@ -133,9 +144,16 @@ enum CredHandler {
cred_id: Uuid,
},
Passkey {
c_wan: CredWebauthn,
c_wan: CredPasskey,
cred_ids: BTreeMap<CredentialID, Uuid>,
},
AttestedPasskey {
c_wan: CredAttestedPasskey,
// To verify the attestation post auth
att_ca_list: AttestationCaList,
// AP does `PartialEq` on cred_id
creds: BTreeMap<AttestedPasskeyV4, Uuid>,
},
}
impl TryFrom<(&Credential, &Webauthn)> for CredHandler {
@ -205,7 +223,7 @@ impl TryFrom<(&Credential, &Webauthn)> for CredHandler {
webauthn
.start_passkey_authentication(&pks)
.map(|(chal, wan_state)| CredHandler::Passkey {
c_wan: CredWebauthn {
c_wan: CredPasskey {
chal,
wan_state,
state: CredVerifyState::Init,
@ -221,31 +239,32 @@ impl TryFrom<(&Credential, &Webauthn)> for CredHandler {
}
}
impl TryFrom<(&BTreeMap<Uuid, (String, PasskeyV4)>, &Webauthn)> for CredHandler {
type Error = ();
impl CredHandler {
/// Given a credential and some external configuration, Generate the credential handler
/// that will be used for this session. This credential handler is a "self contained"
/// unit that defines what is possible to use during this authentication session to prevent
/// inconsistency.
fn try_from(
(wan, webauthn): (&BTreeMap<Uuid, (String, PasskeyV4)>, &Webauthn),
) -> Result<Self, Self::Error> {
if wan.is_empty() {
security_info!("Account does not have any passkeys");
return Err(());
fn build_from_set_passkey(
wan: impl Iterator<Item = (Uuid, PasskeyV4)>,
webauthn: &Webauthn,
) -> Result<Self, ()> {
let mut pks = Vec::with_capacity(wan.size_hint().0);
let mut cred_ids = BTreeMap::default();
for (uuid, pk) in wan {
cred_ids.insert(pk.cred_id().clone(), uuid);
pks.push(pk);
}
let pks: Vec<_> = wan.values().map(|(_, k)| k).cloned().collect();
let cred_ids: BTreeMap<_, _> = wan
.iter()
.map(|(u, (_, k))| (k.cred_id().clone(), *u))
.collect();
if pks.is_empty() {
security_info!("Account does not have any passkeys");
return Err(());
};
webauthn
.start_passkey_authentication(&pks)
.map(|(chal, wan_state)| CredHandler::Passkey {
c_wan: CredWebauthn {
c_wan: CredPasskey {
chal,
wan_state,
state: CredVerifyState::Init,
@ -260,20 +279,19 @@ impl TryFrom<(&BTreeMap<Uuid, (String, PasskeyV4)>, &Webauthn)> for CredHandler
// maps to unit.
})
}
}
impl TryFrom<(Uuid, &PasskeyV4, &Webauthn)> for CredHandler {
type Error = ();
fn try_from(
(cred_id, pk, webauthn): (Uuid, &PasskeyV4, &Webauthn),
) -> Result<Self, Self::Error> {
fn build_from_single_passkey(
cred_id: Uuid,
pk: PasskeyV4,
webauthn: &Webauthn,
) -> Result<Self, ()> {
let cred_ids = btreemap!((pk.cred_id().clone(), cred_id));
let pks = vec![pk.clone()];
let pks = vec![pk];
webauthn
.start_passkey_authentication(pks.as_slice())
.map(|(chal, wan_state)| CredHandler::Passkey {
c_wan: CredWebauthn {
c_wan: CredPasskey {
chal,
wan_state,
state: CredVerifyState::Init,
@ -288,9 +306,69 @@ impl TryFrom<(Uuid, &PasskeyV4, &Webauthn)> for CredHandler {
// maps to unit.
})
}
}
impl CredHandler {
fn build_from_set_attested_pk(
wan: &BTreeMap<Uuid, (String, AttestedPasskeyV4)>,
att_ca_list: &AttestationCaList,
webauthn: &Webauthn,
) -> Result<Self, ()> {
if wan.is_empty() {
security_info!("Account does not have any attested passkeys");
return Err(());
};
let pks: Vec<_> = wan.values().map(|(_, k)| k).cloned().collect();
let creds: BTreeMap<_, _> = wan.iter().map(|(u, (_, k))| (k.clone(), *u)).collect();
webauthn
.start_attested_passkey_authentication(&pks)
.map(|(chal, wan_state)| CredHandler::AttestedPasskey {
c_wan: CredAttestedPasskey {
chal,
wan_state,
state: CredVerifyState::Init,
},
att_ca_list: att_ca_list.clone(),
creds,
})
.map_err(|e| {
security_info!(
?e,
"Unable to create attested passkey webauthn authentication challenge"
);
// maps to unit.
})
}
fn build_from_single_attested_pk(
cred_id: Uuid,
pk: &AttestedPasskeyV4,
att_ca_list: &AttestationCaList,
webauthn: &Webauthn,
) -> Result<Self, ()> {
let creds = btreemap!((pk.clone(), cred_id));
let pks = vec![pk.clone()];
webauthn
.start_attested_passkey_authentication(pks.as_slice())
.map(|(chal, wan_state)| CredHandler::AttestedPasskey {
c_wan: CredAttestedPasskey {
chal,
wan_state,
state: CredVerifyState::Init,
},
att_ca_list: att_ca_list.clone(),
creds,
})
.map_err(|e| {
security_info!(
?e,
"Unable to create attested passkey webauthn authentication challenge"
);
// maps to unit.
})
}
/// Determine if this password factor requires an upgrade of it's cryptographic type. If
/// so, send an asynchronous event into the queue that will allow the password to have it's
/// content upgraded later.
@ -527,10 +605,10 @@ impl CredHandler {
// end CredHandler::PasswordMfa
/// Validate a webauthn authentication attempt
pub fn validate_webauthn(
pub fn validate_passkey(
cred: &AuthCredential,
cred_ids: &BTreeMap<CredentialID, Uuid>,
wan_cred: &mut CredWebauthn,
wan_cred: &mut CredPasskey,
webauthn: &Webauthn,
who: Uuid,
async_tx: &Sender<DelayedAction>,
@ -591,6 +669,82 @@ impl CredHandler {
}
}
/// Validate a webauthn authentication attempt
pub fn validate_attested_passkey(
cred: &AuthCredential,
creds: &BTreeMap<AttestedPasskeyV4, Uuid>,
wan_cred: &mut CredAttestedPasskey,
webauthn: &Webauthn,
who: Uuid,
async_tx: &Sender<DelayedAction>,
att_ca_list: &AttestationCaList,
) -> CredState {
if wan_cred.state != CredVerifyState::Init {
security_error!("Handler::Webauthn -> Result::Denied - Internal State Already Fail");
return CredState::Denied(BAD_WEBAUTHN_MSG);
}
match cred {
AuthCredential::Passkey(resp) => {
// lets see how we go.
match webauthn.finish_attested_passkey_authentication(resp, &wan_cred.wan_state) {
Ok(auth_result) => {
if let Some((apk, cred_id)) = creds.get_key_value(auth_result.cred_id()) {
// Verify attestation of the key.
if let Err(webauthn_err) = apk.verify_attestation(att_ca_list) {
wan_cred.state = CredVerifyState::Fail;
// Denied.
debug!(?webauthn_err);
security_error!("Handler::Webauthn -> Result::Denied - webauthn credential fails attestation");
return CredState::Denied(BAD_ACCOUNT_POLICY);
}
wan_cred.state = CredVerifyState::Success;
// Success. Determine if we need to update the counter
// async from r.
if auth_result.needs_update() {
// Do async
if let Err(_e) =
async_tx.send(DelayedAction::WebauthnCounterIncrement(
WebauthnCounterIncrement {
target_uuid: who,
auth_result,
},
))
{
admin_warn!("unable to queue delayed webauthn property update, continuing ... ");
};
};
CredState::Success {
auth_type: AuthType::AttestedPasskey,
cred_id: *cred_id,
}
} else {
wan_cred.state = CredVerifyState::Fail;
// Denied.
security_error!("Handler::Webauthn -> Result::Denied - webauthn credential id not found");
CredState::Denied(BAD_WEBAUTHN_MSG)
}
}
Err(e) => {
wan_cred.state = CredVerifyState::Fail;
// Denied.
security_error!(?e, "Handler::Webauthn -> Result::Denied - webauthn error");
CredState::Denied(BAD_WEBAUTHN_MSG)
}
}
}
_ => {
security_error!(
"Handler::Webauthn -> Result::Denied - invalid cred type for handler"
);
CredState::Denied(BAD_AUTH_TYPE_MSG)
}
}
}
#[allow(clippy::too_many_arguments)]
/// Given the current handler, proceed to authenticate the attempted credential step.
pub fn validate(
@ -633,7 +787,20 @@ impl CredHandler {
CredHandler::Passkey {
ref mut c_wan,
cred_ids,
} => Self::validate_webauthn(cred, cred_ids, c_wan, webauthn, who, async_tx),
} => Self::validate_passkey(cred, cred_ids, c_wan, webauthn, who, async_tx),
CredHandler::AttestedPasskey {
ref mut c_wan,
ref att_ca_list,
creds,
} => Self::validate_attested_passkey(
cred,
creds,
c_wan,
webauthn,
who,
async_tx,
att_ca_list,
),
}
}
@ -659,6 +826,9 @@ impl CredHandler {
)
.collect(),
CredHandler::Passkey { c_wan, .. } => vec![AuthAllowed::Passkey(c_wan.chal.clone())],
CredHandler::AttestedPasskey { c_wan, .. } => {
vec![AuthAllowed::Passkey(c_wan.chal.clone())]
}
}
}
@ -668,7 +838,8 @@ impl CredHandler {
(CredHandler::Anonymous { .. }, AuthMech::Anonymous)
| (CredHandler::Password { .. }, AuthMech::Password)
| (CredHandler::PasswordMfa { .. }, AuthMech::PasswordMfa)
| (CredHandler::Passkey { .. }, AuthMech::Passkey) => true,
| (CredHandler::Passkey { .. }, AuthMech::Passkey)
| (CredHandler::AttestedPasskey { .. }, AuthMech::Passkey) => true,
(_, _) => false,
}
}
@ -679,6 +850,7 @@ impl CredHandler {
CredHandler::Password { .. } => AuthMech::Password,
CredHandler::PasswordMfa { .. } => AuthMech::PasswordMfa,
CredHandler::Passkey { .. } => AuthMech::Passkey,
CredHandler::AttestedPasskey { .. } => AuthMech::Passkey,
}
}
}
@ -767,9 +939,13 @@ impl AuthSession {
// What's valid to use in this context?
let mut handlers = Vec::new();
// TODO: We can't yet fully enforce account policy on auth, there is a bit of work
// to do to be able to check for pw / mfa etc.
// A possible gotcha is service accounts which can't be affected by these policies?
// let cred_type_min = asd.account_policy.credential_policy();
if let Some(cred) = &asd.account.primary {
// TODO: Make it possible to have multiple creds.
// Probably means new authsession has to be failable
if let Ok(ch) = CredHandler::try_from((cred, asd.webauthn)) {
handlers.push(ch);
} else {
@ -779,8 +955,33 @@ impl AuthSession {
}
}
if let Ok(ch) = CredHandler::try_from((&asd.account.passkeys, asd.webauthn)) {
handlers.push(ch);
// Important - if attested is present, don't use passkeys
if let Some(att_ca_list) = asd.account_policy.webauthn_attestation_ca_list() {
if let Ok(ch) = CredHandler::build_from_set_attested_pk(
&asd.account.attested_passkeys,
att_ca_list,
asd.webauthn,
) {
handlers.push(ch);
}
} else {
let credential_iter = asd
.account
.passkeys
.iter()
.map(|(u, (_, pk))| (*u, pk.clone()))
.chain(
asd.account
.attested_passkeys
.iter()
.map(|(u, (_, pk))| (*u, pk.into())),
);
if let Ok(ch) =
CredHandler::build_from_set_passkey(credential_iter, asd.webauthn)
{
handlers.push(ch);
}
};
if let Some(non_empty_handlers) = NonEmpty::collect(handlers) {
@ -847,6 +1048,9 @@ impl AuthSession {
// Do we need to double check for anon here? I don't think so since the
// anon cred_id won't ever exist on an account.
// We can't yet fully enforce account policy on auth, there is a bit of work
// to do to be able to check the credential types match what we expect.
let mut cred_handler = None;
if let Some(primary) = asd.account.primary.as_ref() {
@ -863,13 +1067,51 @@ impl AuthSession {
}
}
if let Some(pk) = asd.account.passkeys.get(&cred_id).map(|(_, pk)| pk) {
if let Ok(ch) = CredHandler::try_from((cred_id, pk, asd.webauthn)) {
// Update it.
debug_assert!(cred_handler.is_none());
cred_handler = Some(ch);
} else {
security_critical!("corrupt credentials, unable to start primary credhandler");
// Do we have an attestation ca list? If so, we only accept attested
// passkeys.
if let Some(att_ca_list) = asd.account_policy.webauthn_attestation_ca_list() {
if let Some(pk) = asd
.account
.attested_passkeys
.get(&cred_id)
.map(|(_, pk)| pk)
{
if let Ok(ch) = CredHandler::build_from_single_attested_pk(
cred_id,
pk,
att_ca_list,
asd.webauthn,
) {
// Update it.
debug_assert!(cred_handler.is_none());
cred_handler = Some(ch);
} else {
security_critical!(
"corrupt credentials, unable to start attested passkey credhandler"
);
}
}
} else {
// Scan both attested and passkeys for the possible credential.
let maybe_pk: Option<PasskeyV4> = asd
.account
.attested_passkeys
.get(&cred_id)
.map(|(_, apk)| apk.into())
.or_else(|| asd.account.passkeys.get(&cred_id).map(|(_, pk)| pk.clone()));
if let Some(pk) = maybe_pk {
if let Ok(ch) =
CredHandler::build_from_single_passkey(cred_id, pk, asd.webauthn)
{
// Update it.
debug_assert!(cred_handler.is_none());
cred_handler = Some(ch);
} else {
security_critical!(
"corrupt credentials, unable to start passkey credhandler"
);
}
}
}
@ -932,7 +1174,8 @@ impl AuthSession {
Ok(Some(*cred_id))
}
AuthSessionState::InProgress(CredHandler::Anonymous { .. })
| AuthSessionState::InProgress(CredHandler::Passkey { .. }) => Ok(None),
| AuthSessionState::InProgress(CredHandler::Passkey { .. })
| AuthSessionState::InProgress(CredHandler::AttestedPasskey { .. }) => Ok(None),
_ => Err(OperationError::InvalidState),
}
}
@ -1126,7 +1369,10 @@ impl AuthSession {
let scope = match auth_type {
AuthType::Anonymous => SessionScope::ReadOnly,
AuthType::GeneratedPassword => SessionScope::ReadWrite,
AuthType::Password | AuthType::PasswordMfa | AuthType::Passkey => {
AuthType::Password
| AuthType::PasswordMfa
| AuthType::Passkey
| AuthType::AttestedPasskey => {
if privileged {
SessionScope::ReadWrite
} else {
@ -1161,7 +1407,8 @@ impl AuthSession {
AuthType::Password
| AuthType::GeneratedPassword
| AuthType::PasswordMfa
| AuthType::Passkey => {
| AuthType::Passkey
| AuthType::AttestedPasskey => {
trace!("⚠️ Queued AuthSessionRecord for {}", self.account.uuid);
async_tx.send(DelayedAction::AuthSessionRecord(AuthSessionRecord {
target_uuid: self.account.uuid,
@ -1194,9 +1441,10 @@ impl AuthSession {
error!("AuthType used in Reauth is not valid for session re-issuance. Rejecting");
return Err(OperationError::InvalidState);
}
AuthType::Password | AuthType::PasswordMfa | AuthType::Passkey => {
SessionScope::PrivilegeCapable
}
AuthType::Password
| AuthType::PasswordMfa
| AuthType::Passkey
| AuthType::AttestedPasskey => SessionScope::PrivilegeCapable,
};
let uat = self

File diff suppressed because it is too large Load diff

View file

@ -36,6 +36,7 @@ lazy_static! {
m.insert(Attribute::AuthSessionExpiry);
m.insert(Attribute::PrivilegeExpiry);
m.insert(Attribute::CredentialTypeMinimum);
m.insert(Attribute::WebauthnAttestationCaList);
m
};
}

View file

@ -64,7 +64,12 @@ impl SessionConsistency {
.chain(
entry.get_ava_passkeys(Attribute::PassKeys)
.iter()
.flat_map(|pks| pks.keys().copied() )
.flat_map(|pks| pks.keys().copied())
)
.chain(
entry.get_ava_attestedpasskeys(Attribute::AttestedPasskeys)
.iter()
.flat_map(|pks| pks.keys().copied())
)
.collect();

View file

@ -11,7 +11,8 @@ use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
use webauthn_rs::prelude::{
AttestedPasskey as DeviceKeyV4, Passkey as PasskeyV4, SecurityKey as SecurityKeyV4,
AttestationCaList, AttestedPasskey as AttestedPasskeyV4, Passkey as PasskeyV4,
SecurityKey as SecurityKeyV4,
};
// Re-export this for our own usage.
@ -156,6 +157,8 @@ pub enum ReplIntentTokenV1 {
#[serde(default)]
passkeys_can_edit: bool,
#[serde(default)]
attested_passkeys_can_edit: bool,
#[serde(default)]
unixcred_can_edit: bool,
#[serde(default)]
sshpubkey_can_edit: bool,
@ -172,6 +175,8 @@ pub enum ReplIntentTokenV1 {
#[serde(default)]
passkeys_can_edit: bool,
#[serde(default)]
attested_passkeys_can_edit: bool,
#[serde(default)]
unixcred_can_edit: bool,
#[serde(default)]
sshpubkey_can_edit: bool,
@ -212,15 +217,15 @@ impl PartialEq for ReplPasskeyV4V1 {
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ReplDeviceKeyV4V1 {
pub struct ReplAttestedPasskeyV4V1 {
pub uuid: Uuid,
pub tag: String,
pub key: DeviceKeyV4,
pub key: AttestedPasskeyV4,
}
impl Eq for ReplDeviceKeyV4V1 {}
impl Eq for ReplAttestedPasskeyV4V1 {}
impl PartialEq for ReplDeviceKeyV4V1 {
impl PartialEq for ReplAttestedPasskeyV4V1 {
fn eq(&self, other: &Self) -> bool {
self.uuid == other.uuid && self.key.cred_id() == other.key.cred_id()
}
@ -325,8 +330,8 @@ pub enum ReplAttrV1 {
Passkey {
set: Vec<ReplPasskeyV4V1>,
},
DeviceKey {
set: Vec<ReplDeviceKeyV4V1>,
AttestedPasskey {
set: Vec<ReplAttestedPasskeyV4V1>,
},
DateTime {
set: Vec<String>,
@ -415,6 +420,9 @@ pub enum ReplAttrV1 {
CredentialType {
set: Vec<u16>,
},
WebauthnAttestationCaList {
ca_list: AttestationCaList,
},
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]

View file

@ -216,7 +216,7 @@ impl SchemaAttribute {
SyntaxType::PrivateBinary => matches!(v, PartialValue::PrivateBinary),
SyntaxType::IntentToken => matches!(v, PartialValue::IntentToken(_)),
SyntaxType::Passkey => matches!(v, PartialValue::Passkey(_)),
SyntaxType::DeviceKey => matches!(v, PartialValue::DeviceKey(_)),
SyntaxType::AttestedPasskey => matches!(v, PartialValue::AttestedPasskey(_)),
// Allow refer types.
SyntaxType::Session => matches!(v, PartialValue::Refer(_)),
SyntaxType::ApiToken => matches!(v, PartialValue::Refer(_)),
@ -231,6 +231,7 @@ impl SchemaAttribute {
SyntaxType::AuditLogString => matches!(v, PartialValue::Utf8(_)),
SyntaxType::Image => matches!(v, PartialValue::Utf8(_)),
SyntaxType::CredentialType => matches!(v, PartialValue::CredentialType(_)),
SyntaxType::WebauthnAttestationCaList => false,
};
if r {
Ok(())
@ -272,7 +273,7 @@ impl SchemaAttribute {
SyntaxType::PrivateBinary => matches!(v, Value::PrivateBinary(_)),
SyntaxType::IntentToken => matches!(v, Value::IntentToken(_, _)),
SyntaxType::Passkey => matches!(v, Value::Passkey(_, _, _)),
SyntaxType::DeviceKey => matches!(v, Value::DeviceKey(_, _, _)),
SyntaxType::AttestedPasskey => matches!(v, Value::AttestedPasskey(_, _, _)),
SyntaxType::Session => matches!(v, Value::Session(_, _)),
SyntaxType::ApiToken => matches!(v, Value::ApiToken(_, _)),
SyntaxType::Oauth2Session => matches!(v, Value::Oauth2Session(_, _)),
@ -284,6 +285,9 @@ impl SchemaAttribute {
SyntaxType::EcKeyPrivate => matches!(v, Value::EcKeyPrivate(_)),
SyntaxType::Image => matches!(v, Value::Image(_)),
SyntaxType::CredentialType => matches!(v, Value::CredentialType(_)),
SyntaxType::WebauthnAttestationCaList => {
matches!(v, Value::WebauthnAttestationCaList(_))
}
};
if r {
Ok(())

View file

@ -566,7 +566,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH.clone().into(),
SCHEMA_ATTR_BADLIST_PASSWORD.clone().into(),
SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN.clone().into(),
SCHEMA_ATTR_DEVICEKEYS.clone().into(),
SCHEMA_ATTR_ATTESTED_PASSKEYS.clone().into(),
SCHEMA_ATTR_DISPLAYNAME.clone().into(),
SCHEMA_ATTR_DOMAIN_DISPLAY_NAME.clone().into(),
SCHEMA_ATTR_DOMAIN_LDAP_BASEDN.clone().into(),
@ -613,6 +613,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION.clone().into(),
SCHEMA_ATTR_DENIED_NAME.clone().into(),
SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM.clone().into(),
SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST.clone().into(),
];
let r = idm_schema

View file

@ -577,11 +577,13 @@ pub trait QueryServerTransaction<'a> {
.ok_or_else(|| OperationError::InvalidAttribute("Invalid Url (whatwg/url) syntax".to_string())),
SyntaxType::OauthScope => Value::new_oauthscope(value)
.ok_or_else(|| OperationError::InvalidAttribute("Invalid Oauth Scope syntax".to_string())),
SyntaxType::WebauthnAttestationCaList => Value::new_webauthn_attestation_ca_list(value)
.ok_or_else(|| OperationError::InvalidAttribute("Invalid Webauthn Attestation CA List".to_string())),
SyntaxType::OauthScopeMap => Err(OperationError::InvalidAttribute("Oauth Scope Maps can not be supplied through modification - please use the IDM api".to_string())),
SyntaxType::PrivateBinary => Err(OperationError::InvalidAttribute("Private Binary Values can not be supplied through modification".to_string())),
SyntaxType::IntentToken => Err(OperationError::InvalidAttribute("Intent Token Values can not be supplied through modification".to_string())),
SyntaxType::Passkey => Err(OperationError::InvalidAttribute("Passkey Values can not be supplied through modification".to_string())),
SyntaxType::DeviceKey => Err(OperationError::InvalidAttribute("DeviceKey Values can not be supplied through modification".to_string())),
SyntaxType::AttestedPasskey => Err(OperationError::InvalidAttribute("AttestedPasskey Values can not be supplied through modification".to_string())),
SyntaxType::Session => Err(OperationError::InvalidAttribute("Session Values can not be supplied through modification".to_string())),
SyntaxType::ApiToken => Err(OperationError::InvalidAttribute("ApiToken Values can not be supplied through modification".to_string())),
SyntaxType::JwsKeyEs256 => Err(OperationError::InvalidAttribute("JwsKeyEs256 Values can not be supplied through modification".to_string())),
@ -634,7 +636,7 @@ pub trait QueryServerTransaction<'a> {
.map(PartialValue::CredentialType)
.map_err(|()| {
OperationError::InvalidAttribute(
"Invalid CredentialType syntax".to_string(),
"Invalid credentialtype syntax".to_string(),
)
}),
SyntaxType::Uuid => {
@ -694,13 +696,12 @@ pub trait QueryServerTransaction<'a> {
SyntaxType::Passkey => PartialValue::new_passkey_s(value).ok_or_else(|| {
OperationError::InvalidAttribute("Invalid Passkey UUID syntax".to_string())
}),
SyntaxType::DeviceKey => {
PartialValue::new_devicekey_s(value).ok_or_else(|| {
SyntaxType::AttestedPasskey => PartialValue::new_attested_passkey_s(value)
.ok_or_else(|| {
OperationError::InvalidAttribute(
"Invalid DeviceKey UUID syntax".to_string(),
"Invalid AttestedPasskey UUID syntax".to_string(),
)
})
}
}),
SyntaxType::UiHint => UiHint::from_str(value)
.map(PartialValue::UiHint)
.map_err(|()| {
@ -709,6 +710,9 @@ pub trait QueryServerTransaction<'a> {
SyntaxType::AuditLogString => Ok(PartialValue::new_utf8s(value)),
SyntaxType::EcKeyPrivate => Ok(PartialValue::SecretValue),
SyntaxType::Image => Ok(PartialValue::new_utf8s(value)),
SyntaxType::WebauthnAttestationCaList => Err(OperationError::InvalidAttribute(
"Invalid - unable to query attestation CA list".to_string(),
)),
}
}
None => {

View file

@ -27,7 +27,9 @@ use sshkey_attest::proto::PublicKey as SshPublicKey;
use time::OffsetDateTime;
use url::Url;
use uuid::Uuid;
use webauthn_rs::prelude::{AttestedPasskey as DeviceKeyV4, Passkey as PasskeyV4};
use webauthn_rs::prelude::{
AttestationCaList, AttestedPasskey as AttestedPasskeyV4, Passkey as PasskeyV4,
};
use crate::be::dbentry::DbIdentSpn;
use crate::credential::{totp::Totp, Credential};
@ -124,6 +126,7 @@ pub struct CredUpdateSessionPerms {
pub ext_cred_portal_can_view: bool,
pub primary_can_edit: bool,
pub passkeys_can_edit: bool,
pub attested_passkeys_can_edit: bool,
pub unixcred_can_edit: bool,
pub sshpubkey_can_edit: bool,
}
@ -248,7 +251,7 @@ pub enum SyntaxType {
PrivateBinary = 21,
IntentToken = 22,
Passkey = 23,
DeviceKey = 24,
AttestedPasskey = 24,
Session = 25,
JwsKeyEs256 = 26,
JwsKeyRs256 = 27,
@ -260,6 +263,7 @@ pub enum SyntaxType {
EcKeyPrivate = 33,
Image = 34,
CredentialType = 35,
WebauthnAttestationCaList = 36,
}
impl TryFrom<&str> for SyntaxType {
@ -293,7 +297,7 @@ impl TryFrom<&str> for SyntaxType {
"PRIVATE_BINARY" => Ok(SyntaxType::PrivateBinary),
"INTENT_TOKEN" => Ok(SyntaxType::IntentToken),
"PASSKEY" => Ok(SyntaxType::Passkey),
"DEVICEKEY" => Ok(SyntaxType::DeviceKey),
"ATTESTED_PASSKEY" => Ok(SyntaxType::AttestedPasskey),
"SESSION" => Ok(SyntaxType::Session),
"JWS_KEY_ES256" => Ok(SyntaxType::JwsKeyEs256),
"JWS_KEY_RS256" => Ok(SyntaxType::JwsKeyRs256),
@ -304,6 +308,7 @@ impl TryFrom<&str> for SyntaxType {
"AUDIT_LOG_STRING" => Ok(SyntaxType::AuditLogString),
"EC_KEY_PRIVATE" => Ok(SyntaxType::EcKeyPrivate),
"CREDENTIAL_TYPE" => Ok(SyntaxType::CredentialType),
"WEBAUTHN_ATTESTATION_CA_LIST" => Ok(SyntaxType::WebauthnAttestationCaList),
_ => Err(()),
}
}
@ -336,7 +341,7 @@ impl fmt::Display for SyntaxType {
SyntaxType::PrivateBinary => "PRIVATE_BINARY",
SyntaxType::IntentToken => "INTENT_TOKEN",
SyntaxType::Passkey => "PASSKEY",
SyntaxType::DeviceKey => "DEVICEKEY",
SyntaxType::AttestedPasskey => "ATTESTED_PASSKEY",
SyntaxType::Session => "SESSION",
SyntaxType::JwsKeyEs256 => "JWS_KEY_ES256",
SyntaxType::JwsKeyRs256 => "JWS_KEY_RS256",
@ -348,6 +353,7 @@ impl fmt::Display for SyntaxType {
SyntaxType::EcKeyPrivate => "EC_KEY_PRIVATE",
SyntaxType::Image => "IMAGE",
SyntaxType::CredentialType => "CREDENTIAL_TYPE",
SyntaxType::WebauthnAttestationCaList => "WEBAUTHN_ATTESTATION_CA_LIST",
})
}
}
@ -461,7 +467,7 @@ pub enum PartialValue {
IntentToken(String),
UiHint(UiHint),
Passkey(Uuid),
DeviceKey(Uuid),
AttestedPasskey(Uuid),
/// We compare on the value hash
Image(String),
CredentialType(CredentialType),
@ -776,8 +782,8 @@ impl PartialValue {
Uuid::parse_str(us).map(PartialValue::Passkey).ok()
}
pub fn new_devicekey_s(us: &str) -> Option<Self> {
Uuid::parse_str(us).map(PartialValue::DeviceKey).ok()
pub fn new_attested_passkey_s(us: &str) -> Option<Self> {
Uuid::parse_str(us).map(PartialValue::AttestedPasskey).ok()
}
pub fn new_image(input: &str) -> Self {
@ -809,7 +815,7 @@ impl PartialValue {
| PartialValue::EmailAddress(s)
| PartialValue::RestrictedString(s) => s.clone(),
PartialValue::Passkey(u)
| PartialValue::DeviceKey(u)
| PartialValue::AttestedPasskey(u)
| PartialValue::Refer(u)
| PartialValue::Uuid(u) => u.as_hyphenated().to_string(),
PartialValue::Bool(b) => b.to_string(),
@ -1023,7 +1029,7 @@ pub enum Value {
RestrictedString(String),
IntentToken(String, IntentTokenState),
Passkey(Uuid, String, PasskeyV4),
DeviceKey(Uuid, String, DeviceKeyV4),
AttestedPasskey(Uuid, String, AttestedPasskeyV4),
Session(Uuid, Session),
ApiToken(Uuid, ApiToken),
@ -1039,6 +1045,7 @@ pub enum Value {
Image(ImageValue),
CredentialType(CredentialType),
WebauthnAttestationCaList(AttestationCaList),
}
impl PartialEq for Value {
@ -1538,6 +1545,15 @@ impl Value {
Value::RestrictedString(s)
}
pub fn new_webauthn_attestation_ca_list(s: &str) -> Option<Self> {
serde_json::from_str(s)
.map(Value::WebauthnAttestationCaList)
.map_err(|err| {
debug!(?err, ?s);
})
.ok()
}
#[allow(clippy::unreachable)]
pub(crate) fn to_db_ident_spn(&self) -> DbIdentSpn {
// This has to clone due to how the backend works.
@ -1788,7 +1804,7 @@ impl Value {
| Value::PublicBinary(s, _)
| Value::IntentToken(s, _)
| Value::Passkey(_, s, _)
| Value::DeviceKey(_, s, _)
| Value::AttestedPasskey(_, s, _)
| Value::TotpSecret(s, _) => {
Value::validate_str_escapes(s) && Value::validate_singleline(s)
}
@ -1846,7 +1862,8 @@ impl Value {
| Value::JwsKeyRs256(_)
| Value::EcKeyPrivate(_)
| Value::UiHint(_)
| Value::CredentialType(_) => true,
| Value::CredentialType(_)
| Value::WebauthnAttestationCaList(_) => true,
}
}

View file

@ -2,15 +2,17 @@ use smolset::SmolSet;
use std::collections::btree_map::Entry as BTreeEntry;
use std::collections::BTreeMap;
use webauthn_rs::prelude::{AttestedPasskey as DeviceKeyV4, Passkey as PasskeyV4};
use webauthn_rs::prelude::{
AttestationCaList, AttestedPasskey as AttestedPasskeyV4, Passkey as PasskeyV4,
};
use crate::be::dbvalue::{
DbValueCredV1, DbValueDeviceKeyV1, DbValueIntentTokenStateV1, DbValuePasskeyV1,
DbValueAttestedPasskeyV1, DbValueCredV1, DbValueIntentTokenStateV1, DbValuePasskeyV1,
};
use crate::credential::Credential;
use crate::prelude::*;
use crate::repl::proto::{
ReplAttrV1, ReplCredV1, ReplDeviceKeyV4V1, ReplIntentTokenV1, ReplPasskeyV4V1,
ReplAttestedPasskeyV4V1, ReplAttrV1, ReplCredV1, ReplIntentTokenV1, ReplPasskeyV4V1,
};
use crate::schema::SchemaAttribute;
use crate::value::{CredUpdateSessionPerms, CredentialType, IntentTokenState};
@ -230,6 +232,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
} => IntentTokenState::Valid {
@ -238,6 +241,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
},
@ -249,6 +253,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
} => IntentTokenState::InProgress {
@ -259,6 +264,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
},
@ -283,6 +289,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
} => (
@ -293,6 +300,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view: *ext_cred_portal_can_view,
primary_can_edit: *primary_can_edit,
passkeys_can_edit: *passkeys_can_edit,
attested_passkeys_can_edit: *attested_passkeys_can_edit,
unixcred_can_edit: *unixcred_can_edit,
sshpubkey_can_edit: *sshpubkey_can_edit,
},
@ -306,6 +314,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
} => (
@ -318,6 +327,7 @@ impl ValueSetIntentToken {
ext_cred_portal_can_view: *ext_cred_portal_can_view,
primary_can_edit: *primary_can_edit,
passkeys_can_edit: *passkeys_can_edit,
attested_passkeys_can_edit: *attested_passkeys_can_edit,
unixcred_can_edit: *unixcred_can_edit,
sshpubkey_can_edit: *sshpubkey_can_edit,
},
@ -435,6 +445,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
},
@ -443,6 +454,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view: *ext_cred_portal_can_view,
primary_can_edit: *primary_can_edit,
passkeys_can_edit: *passkeys_can_edit,
attested_passkeys_can_edit: *attested_passkeys_can_edit,
unixcred_can_edit: *unixcred_can_edit,
sshpubkey_can_edit: *sshpubkey_can_edit,
},
@ -455,6 +467,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
},
@ -465,6 +478,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view: *ext_cred_portal_can_view,
primary_can_edit: *primary_can_edit,
passkeys_can_edit: *passkeys_can_edit,
attested_passkeys_can_edit: *attested_passkeys_can_edit,
unixcred_can_edit: *unixcred_can_edit,
sshpubkey_can_edit: *sshpubkey_can_edit,
},
@ -491,6 +505,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
},
@ -500,6 +515,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view: *ext_cred_portal_can_view,
primary_can_edit: *primary_can_edit,
passkeys_can_edit: *passkeys_can_edit,
attested_passkeys_can_edit: *attested_passkeys_can_edit,
unixcred_can_edit: *unixcred_can_edit,
sshpubkey_can_edit: *sshpubkey_can_edit,
},
@ -512,6 +528,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view,
primary_can_edit,
passkeys_can_edit,
attested_passkeys_can_edit,
unixcred_can_edit,
sshpubkey_can_edit,
},
@ -523,6 +540,7 @@ impl ValueSetT for ValueSetIntentToken {
ext_cred_portal_can_view: *ext_cred_portal_can_view,
primary_can_edit: *primary_can_edit,
passkeys_can_edit: *passkeys_can_edit,
attested_passkeys_can_edit: *attested_passkeys_can_edit,
unixcred_can_edit: *unixcred_can_edit,
sshpubkey_can_edit: *sshpubkey_can_edit,
},
@ -768,38 +786,38 @@ impl ValueSetT for ValueSetPasskey {
}
#[derive(Debug, Clone)]
pub struct ValueSetDeviceKey {
map: BTreeMap<Uuid, (String, DeviceKeyV4)>,
pub struct ValueSetAttestedPasskey {
map: BTreeMap<Uuid, (String, AttestedPasskeyV4)>,
}
impl ValueSetDeviceKey {
pub fn new(u: Uuid, t: String, k: DeviceKeyV4) -> Box<Self> {
impl ValueSetAttestedPasskey {
pub fn new(u: Uuid, t: String, k: AttestedPasskeyV4) -> Box<Self> {
let mut map = BTreeMap::new();
map.insert(u, (t, k));
Box::new(ValueSetDeviceKey { map })
Box::new(ValueSetAttestedPasskey { map })
}
pub fn push(&mut self, u: Uuid, t: String, k: DeviceKeyV4) -> bool {
pub fn push(&mut self, u: Uuid, t: String, k: AttestedPasskeyV4) -> bool {
self.map.insert(u, (t, k)).is_none()
}
pub fn from_dbvs2(data: Vec<DbValueDeviceKeyV1>) -> Result<ValueSet, OperationError> {
pub fn from_dbvs2(data: Vec<DbValueAttestedPasskeyV1>) -> Result<ValueSet, OperationError> {
let map = data
.into_iter()
.map(|k| match k {
DbValueDeviceKeyV1::V4 { u, t, k } => Ok((u, (t, k))),
DbValueAttestedPasskeyV1::V4 { u, t, k } => Ok((u, (t, k))),
})
.collect::<Result<_, _>>()?;
Ok(Box::new(ValueSetDeviceKey { map }))
Ok(Box::new(ValueSetAttestedPasskey { map }))
}
pub fn from_repl_v1(data: &[ReplDeviceKeyV4V1]) -> Result<ValueSet, OperationError> {
pub fn from_repl_v1(data: &[ReplAttestedPasskeyV4V1]) -> Result<ValueSet, OperationError> {
let map = data
.iter()
.cloned()
.map(|ReplDeviceKeyV4V1 { uuid, tag, key }| Ok((uuid, (tag, key))))
.map(|ReplAttestedPasskeyV4V1 { uuid, tag, key }| Ok((uuid, (tag, key))))
.collect::<Result<_, _>>()?;
Ok(Box::new(ValueSetDeviceKey { map }))
Ok(Box::new(ValueSetAttestedPasskey { map }))
}
// We need to allow this, because rust doesn't allow us to impl FromIterator on foreign
@ -807,17 +825,17 @@ impl ValueSetDeviceKey {
#[allow(clippy::should_implement_trait)]
pub fn from_iter<T>(iter: T) -> Option<Box<Self>>
where
T: IntoIterator<Item = (Uuid, String, DeviceKeyV4)>,
T: IntoIterator<Item = (Uuid, String, AttestedPasskeyV4)>,
{
let map = iter.into_iter().map(|(u, t, k)| (u, (t, k))).collect();
Some(Box::new(ValueSetDeviceKey { map }))
Some(Box::new(ValueSetAttestedPasskey { map }))
}
}
impl ValueSetT for ValueSetDeviceKey {
impl ValueSetT for ValueSetAttestedPasskey {
fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
match value {
Value::DeviceKey(u, t, k) => {
Value::AttestedPasskey(u, t, k) => {
if let BTreeEntry::Vacant(e) = self.map.entry(u) {
e.insert((t, k));
Ok(true)
@ -835,14 +853,14 @@ impl ValueSetT for ValueSetDeviceKey {
fn remove(&mut self, pv: &PartialValue, _cid: &Cid) -> bool {
match pv {
PartialValue::DeviceKey(u) => self.map.remove(u).is_some(),
PartialValue::AttestedPasskey(u) => self.map.remove(u).is_some(),
_ => false,
}
}
fn contains(&self, pv: &PartialValue) -> bool {
match pv {
PartialValue::DeviceKey(u) => self.map.contains_key(u),
PartialValue::AttestedPasskey(u) => self.map.contains_key(u),
_ => false,
}
}
@ -875,7 +893,7 @@ impl ValueSetT for ValueSetDeviceKey {
}
fn syntax(&self) -> SyntaxType {
SyntaxType::DeviceKey
SyntaxType::AttestedPasskey
}
fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
@ -889,10 +907,10 @@ impl ValueSetT for ValueSetDeviceKey {
}
fn to_db_valueset_v2(&self) -> DbValueSetV2 {
DbValueSetV2::DeviceKey(
DbValueSetV2::AttestedPasskey(
self.map
.iter()
.map(|(u, (t, k))| DbValueDeviceKeyV1::V4 {
.map(|(u, (t, k))| DbValueAttestedPasskeyV1::V4 {
u: *u,
t: t.clone(),
k: k.clone(),
@ -902,11 +920,11 @@ impl ValueSetT for ValueSetDeviceKey {
}
fn to_repl_v1(&self) -> ReplAttrV1 {
ReplAttrV1::DeviceKey {
ReplAttrV1::AttestedPasskey {
set: self
.map
.iter()
.map(|(u, (t, k))| ReplDeviceKeyV4V1 {
.map(|(u, (t, k))| ReplAttestedPasskeyV4V1 {
uuid: *u,
tag: t.clone(),
key: k.clone(),
@ -916,20 +934,20 @@ impl ValueSetT for ValueSetDeviceKey {
}
fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
Box::new(self.map.keys().copied().map(PartialValue::DeviceKey))
Box::new(self.map.keys().copied().map(PartialValue::AttestedPasskey))
}
fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
Box::new(
self.map
.iter()
.map(|(u, (t, k))| Value::DeviceKey(*u, t.clone(), k.clone())),
.map(|(u, (t, k))| Value::AttestedPasskey(*u, t.clone(), k.clone())),
)
}
fn equal(&self, other: &ValueSet) -> bool {
// Looks like we may not need this?
if let Some(other) = other.as_devicekey_map() {
if let Some(other) = other.as_attestedpasskey_map() {
&self.map == other
} else {
// debug_assert!(false);
@ -938,7 +956,7 @@ impl ValueSetT for ValueSetDeviceKey {
}
fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
if let Some(b) = other.as_devicekey_map() {
if let Some(b) = other.as_attestedpasskey_map() {
mergemaps!(self.map, b)
} else {
debug_assert!(false);
@ -946,15 +964,17 @@ impl ValueSetT for ValueSetDeviceKey {
}
}
fn to_devicekey_single(&self) -> Option<&DeviceKeyV4> {
/*
fn to_attestedpasskey_single(&self) -> Option<&AttestedPasskeyV4> {
if self.map.len() == 1 {
self.map.values().take(1).next().map(|(_, k)| k)
} else {
None
}
}
*/
fn as_devicekey_map(&self) -> Option<&BTreeMap<Uuid, (String, DeviceKeyV4)>> {
fn as_attestedpasskey_map(&self) -> Option<&BTreeMap<Uuid, (String, AttestedPasskeyV4)>> {
Some(&self.map)
}
}
@ -1115,3 +1135,175 @@ impl ValueSetT for ValueSetCredentialType {
Some(&self.set)
}
}
#[derive(Debug, Clone)]
pub struct ValueSetWebauthnAttestationCaList {
ca_list: AttestationCaList,
}
impl ValueSetWebauthnAttestationCaList {
pub fn new(ca_list: AttestationCaList) -> Box<Self> {
Box::new(ValueSetWebauthnAttestationCaList { ca_list })
}
/*
pub fn push(&mut self, u: CredentialType) -> bool {
self.set.insert(u)
}
*/
pub fn from_dbvs2(ca_list: AttestationCaList) -> Result<ValueSet, OperationError> {
Ok(Box::new(ValueSetWebauthnAttestationCaList { ca_list }))
}
pub fn from_repl_v1(ca_list: &AttestationCaList) -> Result<ValueSet, OperationError> {
Ok(Box::new(ValueSetWebauthnAttestationCaList {
ca_list: ca_list.clone(),
}))
}
/*
// We need to allow this, because rust doesn't allow us to impl FromIterator on foreign
// types, and uuid is foreign.
#[allow(clippy::should_implement_trait)]
pub fn from_iter<T>(iter: T) -> Option<Box<Self>>
where
T: IntoIterator<Item = CredentialType>,
{
let set = iter.into_iter().collect();
Some(Box::new(ValueSetCredentialType { set }))
}
*/
}
impl ValueSetT for ValueSetWebauthnAttestationCaList {
fn insert_checked(&mut self, value: Value) -> Result<bool, OperationError> {
match value {
Value::WebauthnAttestationCaList(u) => {
self.ca_list.union(&u);
Ok(true)
}
_ => {
debug_assert!(false);
Err(OperationError::InvalidValueState)
}
}
}
fn clear(&mut self) {
self.ca_list.clear();
}
fn remove(&mut self, _pv: &PartialValue, _cid: &Cid) -> bool {
/*
match pv {
_ => {
debug_assert!(false);
true
}
}
*/
debug_assert!(false);
true
}
fn contains(&self, _pv: &PartialValue) -> bool {
/*
match pv {
PartialValue::CredentialType(u) => self.set.contains(u),
_ => false,
}
*/
false
}
fn substring(&self, _pv: &PartialValue) -> bool {
false
}
fn startswith(&self, _pv: &PartialValue) -> bool {
false
}
fn endswith(&self, _pv: &PartialValue) -> bool {
false
}
fn lessthan(&self, _pv: &PartialValue) -> bool {
false
}
fn len(&self) -> usize {
self.ca_list.len()
}
fn generate_idx_eq_keys(&self) -> Vec<String> {
// self.set.iter().map(|u| u.to_string()).collect()
Vec::with_capacity(0)
}
fn syntax(&self) -> SyntaxType {
SyntaxType::WebauthnAttestationCaList
}
fn validate(&self, _schema_attr: &SchemaAttribute) -> bool {
// Should we actually be looking through the ca-list as given and eliminate
// known vuln devices?
true
}
fn to_proto_string_clone_iter(&self) -> Box<dyn Iterator<Item = String> + '_> {
Box::new(
self.ca_list
.cas()
.values()
.flat_map(|att_ca| att_ca.aaguids().values())
.map(|device| device.description_en().to_string()),
)
}
fn to_db_valueset_v2(&self) -> DbValueSetV2 {
DbValueSetV2::WebauthnAttestationCaList {
ca_list: self.ca_list.clone(),
}
}
fn to_repl_v1(&self) -> ReplAttrV1 {
ReplAttrV1::WebauthnAttestationCaList {
ca_list: self.ca_list.clone(),
}
}
fn to_partialvalue_iter(&self) -> Box<dyn Iterator<Item = PartialValue> + '_> {
Box::new(std::iter::empty::<PartialValue>())
}
fn to_value_iter(&self) -> Box<dyn Iterator<Item = Value> + '_> {
Box::new(std::iter::once(Value::WebauthnAttestationCaList(
self.ca_list.clone(),
)))
}
fn equal(&self, other: &ValueSet) -> bool {
if let Some(other) = other.as_webauthn_attestation_ca_list() {
&self.ca_list == other
} else {
debug_assert!(false);
false
}
}
fn merge(&mut self, other: &ValueSet) -> Result<(), OperationError> {
if let Some(b) = other.as_webauthn_attestation_ca_list() {
self.ca_list.union(b);
Ok(())
} else {
debug_assert!(false);
Err(OperationError::InvalidValueState)
}
}
fn as_webauthn_attestation_ca_list(&self) -> Option<&AttestationCaList> {
Some(&self.ca_list)
}
}

View file

@ -8,10 +8,10 @@ use openssl::ec::EcKey;
use openssl::pkey::Private;
use openssl::pkey::Public;
use smolset::SmolSet;
use time::OffsetDateTime;
// use std::fmt::Debug;
use sshkey_attest::proto::PublicKey as SshPublicKey;
use webauthn_rs::prelude::AttestedPasskey as DeviceKeyV4;
use time::OffsetDateTime;
use webauthn_rs::prelude::AttestationCaList;
use webauthn_rs::prelude::AttestedPasskey as AttestedPasskeyV4;
use webauthn_rs::prelude::Passkey as PasskeyV4;
use kanidm_proto::v1::Filter as ProtoFilter;
@ -30,8 +30,8 @@ pub use self::binary::{ValueSetPrivateBinary, ValueSetPublicBinary};
pub use self::bool::ValueSetBool;
pub use self::cid::ValueSetCid;
pub use self::cred::{
ValueSetCredential, ValueSetCredentialType, ValueSetDeviceKey, ValueSetIntentToken,
ValueSetPasskey,
ValueSetAttestedPasskey, ValueSetCredential, ValueSetCredentialType, ValueSetIntentToken,
ValueSetPasskey, ValueSetWebauthnAttestationCaList,
};
pub use self::datetime::ValueSetDateTime;
pub use self::eckey::ValueSetEcKeyPrivate;
@ -355,7 +355,12 @@ pub trait ValueSetT: std::fmt::Debug + DynClone {
None
}
fn as_devicekey_map(&self) -> Option<&BTreeMap<Uuid, (String, DeviceKeyV4)>> {
fn as_attestedpasskey_map(&self) -> Option<&BTreeMap<Uuid, (String, AttestedPasskeyV4)>> {
debug_assert!(false);
None
}
fn as_webauthn_attestation_ca_list(&self) -> Option<&AttestationCaList> {
debug_assert!(false);
None
}
@ -507,11 +512,6 @@ pub trait ValueSetT: std::fmt::Debug + DynClone {
None
}
fn to_devicekey_single(&self) -> Option<&DeviceKeyV4> {
debug_assert!(false);
None
}
fn as_session_map(&self) -> Option<&BTreeMap<Uuid, Session>> {
debug_assert!(false);
None
@ -668,9 +668,10 @@ pub fn from_result_value_iter(
Value::EcKeyPrivate(k) => ValueSetEcKeyPrivate::new(&k),
Value::Image(imagevalue) => image::ValueSetImage::new(imagevalue),
Value::CredentialType(c) => ValueSetCredentialType::new(c),
Value::PhoneNumber(_, _)
Value::WebauthnAttestationCaList(_)
| Value::PhoneNumber(_, _)
| Value::Passkey(_, _, _)
| Value::DeviceKey(_, _, _)
| Value::AttestedPasskey(_, _, _)
| Value::TotpSecret(_, _)
| Value::Session(_, _)
| Value::ApiToken(_, _)
@ -724,7 +725,7 @@ pub fn from_value_iter(mut iter: impl Iterator<Item = Value>) -> Result<ValueSet
Value::IntentToken(u, s) => ValueSetIntentToken::new(u, s),
Value::EmailAddress(a, _) => ValueSetEmailAddress::new(a),
Value::Passkey(u, t, k) => ValueSetPasskey::new(u, t, k),
Value::DeviceKey(u, t, k) => ValueSetDeviceKey::new(u, t, k),
Value::AttestedPasskey(u, t, k) => ValueSetAttestedPasskey::new(u, t, k),
Value::JwsKeyEs256(k) => ValueSetJwsKeyEs256::new(k),
Value::JwsKeyRs256(k) => ValueSetJwsKeyRs256::new(k),
Value::Session(u, m) => ValueSetSession::new(u, m),
@ -736,6 +737,9 @@ pub fn from_value_iter(mut iter: impl Iterator<Item = Value>) -> Result<ValueSet
Value::EcKeyPrivate(k) => ValueSetEcKeyPrivate::new(&k),
Value::Image(imagevalue) => image::ValueSetImage::new(imagevalue),
Value::CredentialType(c) => ValueSetCredentialType::new(c),
Value::WebauthnAttestationCaList(ca_list) => {
ValueSetWebauthnAttestationCaList::new(ca_list)
}
Value::PhoneNumber(_, _) => {
debug_assert!(false);
return Err(OperationError::InvalidValueState);
@ -777,7 +781,7 @@ pub fn from_db_valueset_v2(dbvs: DbValueSetV2) -> Result<ValueSet, OperationErro
DbValueSetV2::IntentToken(set) => ValueSetIntentToken::from_dbvs2(set),
DbValueSetV2::EmailAddress(primary, set) => ValueSetEmailAddress::from_dbvs2(primary, set),
DbValueSetV2::Passkey(set) => ValueSetPasskey::from_dbvs2(set),
DbValueSetV2::DeviceKey(set) => ValueSetDeviceKey::from_dbvs2(set),
DbValueSetV2::AttestedPasskey(set) => ValueSetAttestedPasskey::from_dbvs2(set),
DbValueSetV2::Session(set) => ValueSetSession::from_dbvs2(set),
DbValueSetV2::ApiToken(set) => ValueSetApiToken::from_dbvs2(set),
DbValueSetV2::Oauth2Session(set) => ValueSetOauth2Session::from_dbvs2(set),
@ -793,6 +797,9 @@ pub fn from_db_valueset_v2(dbvs: DbValueSetV2) -> Result<ValueSet, OperationErro
}
DbValueSetV2::Image(set) => ValueSetImage::from_dbvs2(&set),
DbValueSetV2::CredentialType(set) => ValueSetCredentialType::from_dbvs2(set),
DbValueSetV2::WebauthnAttestationCaList { ca_list } => {
ValueSetWebauthnAttestationCaList::from_dbvs2(ca_list)
}
}
}
@ -823,7 +830,7 @@ pub fn from_repl_v1(rv1: &ReplAttrV1) -> Result<ValueSet, OperationError> {
ReplAttrV1::Credential { set } => ValueSetCredential::from_repl_v1(set),
ReplAttrV1::IntentToken { set } => ValueSetIntentToken::from_repl_v1(set),
ReplAttrV1::Passkey { set } => ValueSetPasskey::from_repl_v1(set),
ReplAttrV1::DeviceKey { set } => ValueSetDeviceKey::from_repl_v1(set),
ReplAttrV1::AttestedPasskey { set } => ValueSetAttestedPasskey::from_repl_v1(set),
ReplAttrV1::DateTime { set } => ValueSetDateTime::from_repl_v1(set),
ReplAttrV1::Url { set } => ValueSetUrl::from_repl_v1(set),
ReplAttrV1::NsUniqueId { set } => ValueSetNsUniqueId::from_repl_v1(set),
@ -839,5 +846,8 @@ pub fn from_repl_v1(rv1: &ReplAttrV1) -> Result<ValueSet, OperationError> {
ReplAttrV1::EcKeyPrivate { key } => ValueSetEcKeyPrivate::from_repl_v1(key),
ReplAttrV1::Image { set } => ValueSetImage::from_repl_v1(set),
ReplAttrV1::CredentialType { set } => ValueSetCredentialType::from_repl_v1(set),
ReplAttrV1::WebauthnAttestationCaList { ca_list } => {
ValueSetWebauthnAttestationCaList::from_repl_v1(ca_list)
}
}
}

View file

@ -223,19 +223,19 @@ function addBorrowedObject(obj) {
}
function __wbg_adapter_38(arg0, arg1, arg2) {
try {
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h3e88c381a9b0da08(arg0, arg1, addBorrowedObject(arg2));
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hecf49fd8e934d63d(arg0, arg1, addBorrowedObject(arg2));
} finally {
heap[stack_pointer++] = undefined;
}
}
function __wbg_adapter_41(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h71282a39cf9f54cc(arg0, arg1, addHeapObject(arg2));
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hbb91bcb76d7d57c6(arg0, arg1, addHeapObject(arg2));
}
function __wbg_adapter_44(arg0, arg1, arg2) {
try {
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h49ac351fd82edf13(arg0, arg1, addBorrowedObject(arg2));
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hf15c46d581e6d848(arg0, arg1, addBorrowedObject(arg2));
} finally {
heap[stack_pointer++] = undefined;
}
@ -397,6 +397,11 @@ function __wbg_get_imports() {
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
};
imports.wbg.__wbg_cachekey_b61393159c57fd7b = function(arg0, arg1) {
const ret = getObject(arg1).__yew_subtree_cache_key;
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
};
imports.wbg.__wbg_subtreeid_e348577f7ef777e3 = function(arg0, arg1) {
const ret = getObject(arg1).__yew_subtree_id;
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
@ -405,11 +410,6 @@ function __wbg_get_imports() {
imports.wbg.__wbg_setsubtreeid_d32e6327eef1f7fc = function(arg0, arg1) {
getObject(arg0).__yew_subtree_id = arg1 >>> 0;
};
imports.wbg.__wbg_cachekey_b61393159c57fd7b = function(arg0, arg1) {
const ret = getObject(arg1).__yew_subtree_cache_key;
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
};
imports.wbg.__wbg_setcachekey_80183b7cfc421143 = function(arg0, arg1) {
getObject(arg0).__yew_subtree_cache_key = arg1 >>> 0;
};
@ -435,10 +435,10 @@ function __wbg_get_imports() {
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
}
};
imports.wbg.__wbg_queueMicrotask_e5949c35d772a669 = function(arg0) {
imports.wbg.__wbg_queueMicrotask_4d890031a6a5a50c = function(arg0) {
queueMicrotask(getObject(arg0));
};
imports.wbg.__wbg_queueMicrotask_2be8b97a81fe4d00 = function(arg0) {
imports.wbg.__wbg_queueMicrotask_adae4bc085237231 = function(arg0) {
const ret = getObject(arg0).queueMicrotask;
return addHeapObject(ret);
};
@ -468,27 +468,27 @@ function __wbg_get_imports() {
wasm.__wbindgen_free(arg0, arg1 * 4, 4);
console.log(...v0);
};
imports.wbg.__wbg_body_11da0c1aa9610cb3 = function(arg0) {
imports.wbg.__wbg_body_64abc9aba1891e91 = function(arg0) {
const ret = getObject(arg0).body;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_createElement_9ce3fdea8322ff34 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_createElement_fdd5c113cb84539e = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).createElement(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_createElementNS_6a08d8f33e767e18 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_createElementNS_524b05a6070757b6 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
const ret = getObject(arg0).createElementNS(arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_createTextNode_01a7250c5ca46b04 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_createTextNode_7ff0c034b2855f66 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).createTextNode(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_querySelector_391afe271b8236d5 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_querySelector_c72dce5ac4b6bc3e = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).querySelector(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Window_cde2416cf5126a72 = function(arg0) {
imports.wbg.__wbg_instanceof_Window_3e5cd1f48c152d01 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Window;
@ -498,31 +498,31 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_document_183cf1eecfdbffee = function(arg0) {
imports.wbg.__wbg_document_d609202d16c38224 = function(arg0) {
const ret = getObject(arg0).document;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_location_61ca61017633c753 = function(arg0) {
imports.wbg.__wbg_location_176c34e89c2c9d80 = function(arg0) {
const ret = getObject(arg0).location;
return addHeapObject(ret);
};
imports.wbg.__wbg_history_56dc869560201113 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_history_80998b7456bf367e = function() { return handleError(function (arg0) {
const ret = getObject(arg0).history;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_localStorage_e11f72e996a4f5d9 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_localStorage_8c507fd281456944 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).localStorage;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_sessionStorage_071949dc646bfd35 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_sessionStorage_adb12b0c8ea06c48 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).sessionStorage;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_fetch_8cebc656dc6b11b1 = function(arg0, arg1) {
imports.wbg.__wbg_fetch_6c415b3a07763878 = function(arg0, arg1) {
const ret = getObject(arg0).fetch(getObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_instanceof_Element_6c7af07f5e6c8d69 = function(arg0) {
imports.wbg.__wbg_instanceof_Element_3f326a19cc457941 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Element;
@ -532,201 +532,127 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_namespaceURI_2dd94d0147ffddf2 = function(arg0, arg1) {
imports.wbg.__wbg_namespaceURI_7cc7ef157e398356 = function(arg0, arg1) {
const ret = getObject(arg1).namespaceURI;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_classList_7fd39dc155235d8a = function(arg0) {
imports.wbg.__wbg_classList_82893a9100db6428 = function(arg0) {
const ret = getObject(arg0).classList;
return addHeapObject(ret);
};
imports.wbg.__wbg_setinnerHTML_b88bf159b62c2334 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setinnerHTML_ce0d6527ce4086f2 = function(arg0, arg1, arg2) {
getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_outerHTML_72dcf3aa34725f10 = function(arg0, arg1) {
imports.wbg.__wbg_outerHTML_b5a8d952b5615778 = function(arg0, arg1) {
const ret = getObject(arg1).outerHTML;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_children_af5a3246832628b1 = function(arg0) {
imports.wbg.__wbg_children_990f38c4f4d5c721 = function(arg0) {
const ret = getObject(arg0).children;
return addHeapObject(ret);
};
imports.wbg.__wbg_removeAttribute_dbd76981f9bb9f59 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_removeAttribute_2e200daefb9f3ed4 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeAttribute(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setAttribute_aebcae2169f2f869 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_setAttribute_e7b72a5e7cfcb5a3 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_getItem_c81cd3ae30cd579a = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_getItem_5395a7e200c31e89 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_removeItem_58a487fe7fc070f0 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_removeItem_c84f914587f36b1a = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setItem_fe04f524052a3839 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_setItem_3786c4c8dd0c9bd0 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_setchecked_5757666239434ecd = function(arg0, arg1) {
imports.wbg.__wbg_setchecked_c1d5c3726082e274 = function(arg0, arg1) {
getObject(arg0).checked = arg1 !== 0;
};
imports.wbg.__wbg_value_5e860795f53217cd = function(arg0, arg1) {
imports.wbg.__wbg_value_e024243a9dae20bc = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_7d187f6cc23d8192 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setvalue_5b3442ff620b4a5d = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_addEventListener_51709b9747ad8980 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
}, arguments) };
imports.wbg.__wbg_removeEventListener_5b1e762a7951280a = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
}, arguments) };
imports.wbg.__wbg_state_78eaa7b6ff3123a0 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).state;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_pushState_8eaca41f86b13910 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
}, arguments) };
imports.wbg.__wbg_href_92490614763f3f7c = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_sethref_2c377515f8ddd13a = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
}, arguments) };
imports.wbg.__wbg_pathname_cd5a90c8f3ab524a = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_search_08fbba2309a249da = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_hash_ced9ee31706e591d = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_headers_4711243cf3bffca0 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithstrandinit_29038da14d09e330 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Response_944e2745b5db71f5 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Response;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_status_7841bb47be2a8f16 = function(arg0) {
const ret = getObject(arg0).status;
return ret;
};
imports.wbg.__wbg_headers_ea7ef583d1564b08 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_json_7f96c90903ae4155 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).json();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_bubbles_c27af65192eb3569 = function(arg0) {
imports.wbg.__wbg_bubbles_f1cdd0584446cad0 = function(arg0) {
const ret = getObject(arg0).bubbles;
return ret;
};
imports.wbg.__wbg_cancelBubble_ee3f70328e901584 = function(arg0) {
imports.wbg.__wbg_cancelBubble_976cfdf7ac449a6c = function(arg0) {
const ret = getObject(arg0).cancelBubble;
return ret;
};
imports.wbg.__wbg_composedPath_ee37eece046b69a2 = function(arg0) {
imports.wbg.__wbg_composedPath_12a068e57a98cf90 = function(arg0) {
const ret = getObject(arg0).composedPath();
return addHeapObject(ret);
};
imports.wbg.__wbg_preventDefault_9299867e06da6909 = function(arg0) {
imports.wbg.__wbg_preventDefault_7f821f72e7c6b5d4 = function(arg0) {
getObject(arg0).preventDefault();
};
imports.wbg.__wbg_get_9470c6584bbde430 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_get_0231cdd369e04a1d = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_set_2912c891505cbc22 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_set_27f236f6d7a28c29 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_parentNode_e1c214fc3f362af0 = function(arg0) {
imports.wbg.__wbg_parentNode_92a7017b3a4fad43 = function(arg0) {
const ret = getObject(arg0).parentNode;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_parentElement_592cb54944d3d002 = function(arg0) {
imports.wbg.__wbg_parentElement_72e144c2e8d9e0b5 = function(arg0) {
const ret = getObject(arg0).parentElement;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_lastChild_b17b3c7498d25bd7 = function(arg0) {
imports.wbg.__wbg_lastChild_a62e3fbaab87f734 = function(arg0) {
const ret = getObject(arg0).lastChild;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_nextSibling_d029031876ed1b1b = function(arg0) {
imports.wbg.__wbg_nextSibling_bafccd3347d24543 = function(arg0) {
const ret = getObject(arg0).nextSibling;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_setnodeValue_321840a6762ab272 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setnodeValue_630c6470d05b600e = function(arg0, arg1, arg2) {
getObject(arg0).nodeValue = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_textContent_d69d000f6081b514 = function(arg0, arg1) {
imports.wbg.__wbg_textContent_2f37235e13f8484b = function(arg0, arg1) {
const ret = getObject(arg1).textContent;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_appendChild_2e6a6c9d1f0d443d = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_appendChild_d30e6b83791d04c0 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).appendChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_insertBefore_bdaeec8969497673 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_insertBefore_726c1640c419e940 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).insertBefore(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_removeChild_a63022ebbfa6ebf5 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_removeChild_942eb9c02243d84d = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).removeChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_ShadowRoot_f85f709c953844de = function(arg0) {
imports.wbg.__wbg_instanceof_ShadowRoot_0bd39e89ab117f86 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof ShadowRoot;
@ -736,141 +662,215 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_host_73c8e95bf9b31ccd = function(arg0) {
imports.wbg.__wbg_host_09eee5e3d9cf59a1 = function(arg0) {
const ret = getObject(arg0).host;
return addHeapObject(ret);
};
imports.wbg.__wbg_add_dc5c00591ed65268 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_addEventListener_374cbfd2bbc19ccf = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
}, arguments) };
imports.wbg.__wbg_removeEventListener_9ece7e86d1135657 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
}, arguments) };
imports.wbg.__wbg_state_ba77b2c3ee29c912 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).state;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_pushState_e159043fce8f87bc = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
}, arguments) };
imports.wbg.__wbg_href_160af2ae1328d7b7 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_sethref_90b000c8b01f96b1 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
}, arguments) };
imports.wbg.__wbg_pathname_1ab7e82aaa4511ff = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_search_9f7ca8896c2d0804 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_hash_be2940ca236b5efc = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_headers_d135d2bb8cc60413 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithstrandinit_f581dff0d19a8b03 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Response_4c3b1446206114d1 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Response;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_status_d6d47ad2837621eb = function(arg0) {
const ret = getObject(arg0).status;
return ret;
};
imports.wbg.__wbg_headers_24def508a7518df9 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_json_34535d9848f043eb = function() { return handleError(function (arg0) {
const ret = getObject(arg0).json();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_add_e0f3c5b6e421c311 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_href_7f944b48b612250e = function(arg0, arg1) {
imports.wbg.__wbg_href_e9aac3826080dcaa = function(arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_pathname_a83d8f2ebefa6791 = function(arg0, arg1) {
imports.wbg.__wbg_pathname_aeafa820be91c325 = function(arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_search_8c5f74fa2d11377e = function(arg0, arg1) {
imports.wbg.__wbg_search_f6e95882a48d3f69 = function(arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setsearch_a168105ad9dbdb8b = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setsearch_4f7d084e0d811add = function(arg0, arg1, arg2) {
getObject(arg0).search = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_hash_f468e7d38a21a76a = function(arg0, arg1) {
imports.wbg.__wbg_hash_0087751acddc8f2a = function(arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_sethash_7c3032584865b2bd = function(arg0, arg1, arg2) {
imports.wbg.__wbg_sethash_bfc9db317a77305c = function(arg0, arg1, arg2) {
getObject(arg0).hash = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_new_d7cd05d9de7d4000 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_new_9e08fd37c1c53142 = function() { return handleError(function (arg0, arg1) {
const ret = new URL(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_newwithbase_604e8dfd42d25665 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_newwithbase_f4989aa5bbd5cc29 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_href_2777cc28ba3aac82 = function(arg0, arg1) {
imports.wbg.__wbg_href_f21dc804d4da134a = function(arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_value_539db729f551be3a = function(arg0, arg1) {
imports.wbg.__wbg_value_57e57170f6952449 = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_15231c60278dee22 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setvalue_a11f3069fd7a1805 = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_get_4a9aa5157afeb382 = function(arg0, arg1) {
imports.wbg.__wbg_get_f01601b5a68d10e3 = function(arg0, arg1) {
const ret = getObject(arg0)[arg1 >>> 0];
return addHeapObject(ret);
};
imports.wbg.__wbg_length_cace2e0b3ddc0502 = function(arg0) {
imports.wbg.__wbg_length_1009b1af0c481d7b = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbg_newnoargs_ccdcae30fd002262 = function(arg0, arg1) {
imports.wbg.__wbg_newnoargs_c62ea9419c21fbac = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_next_15da6a3df9290720 = function(arg0) {
imports.wbg.__wbg_next_9b877f231f476d01 = function(arg0) {
const ret = getObject(arg0).next;
return addHeapObject(ret);
};
imports.wbg.__wbg_next_1989a20442400aaa = function() { return handleError(function (arg0) {
imports.wbg.__wbg_next_6529ee0cca8d57ed = function() { return handleError(function (arg0) {
const ret = getObject(arg0).next();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_done_bc26bf4ada718266 = function(arg0) {
imports.wbg.__wbg_done_5fe336b092d60cf2 = function(arg0) {
const ret = getObject(arg0).done;
return ret;
};
imports.wbg.__wbg_value_0570714ff7d75f35 = function(arg0) {
imports.wbg.__wbg_value_0c248a78fdc8e19f = function(arg0) {
const ret = getObject(arg0).value;
return addHeapObject(ret);
};
imports.wbg.__wbg_iterator_7ee1a391d310f8e4 = function() {
imports.wbg.__wbg_iterator_db7ca081358d4fb2 = function() {
const ret = Symbol.iterator;
return addHeapObject(ret);
};
imports.wbg.__wbg_get_2aff440840bb6202 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_get_7b48513de5dc5ea4 = function() { return handleError(function (arg0, arg1) {
const ret = Reflect.get(getObject(arg0), getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_call_669127b9d730c650 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_call_90c26b09837aba1c = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).call(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_new_c728d68b8b34487e = function() {
imports.wbg.__wbg_new_9fb8d994e1c0aaac = function() {
const ret = new Object();
return addHeapObject(ret);
};
imports.wbg.__wbg_self_3fad056edded10bd = function() { return handleError(function () {
imports.wbg.__wbg_self_f0e34d89f33b99fd = function() { return handleError(function () {
const ret = self.self;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_window_a4f46c98a61d4089 = function() { return handleError(function () {
imports.wbg.__wbg_window_d3b084224f4774d7 = function() { return handleError(function () {
const ret = window.window;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_globalThis_17eff828815f7d84 = function() { return handleError(function () {
imports.wbg.__wbg_globalThis_9caa27ff917c6860 = function() { return handleError(function () {
const ret = globalThis.globalThis;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_global_46f939f6541643c5 = function() { return handleError(function () {
imports.wbg.__wbg_global_35dfdd59a4da3e74 = function() { return handleError(function () {
const ret = global.global;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_from_ba72c50feaf1d8c0 = function(arg0) {
imports.wbg.__wbg_from_71add2e723d1f1b2 = function(arg0) {
const ret = Array.from(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_isArray_38525be7442aa21e = function(arg0) {
imports.wbg.__wbg_isArray_74fb723e24f76012 = function(arg0) {
const ret = Array.isArray(getObject(arg0));
return ret;
};
imports.wbg.__wbg_instanceof_ArrayBuffer_c7cc317e5c29cc0d = function(arg0) {
imports.wbg.__wbg_instanceof_ArrayBuffer_e7d53d51371448e2 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof ArrayBuffer;
@ -880,7 +880,7 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_Error_9f5881c3c4149389 = function(arg0) {
imports.wbg.__wbg_instanceof_Error_31ca8d97f188bfbc = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Error;
@ -890,58 +890,58 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_message_35f9b952e1b922e2 = function(arg0) {
imports.wbg.__wbg_message_55b9ea8030688597 = function(arg0) {
const ret = getObject(arg0).message;
return addHeapObject(ret);
};
imports.wbg.__wbg_name_e1152a59269f79e5 = function(arg0) {
imports.wbg.__wbg_name_e5eede664187fed6 = function(arg0) {
const ret = getObject(arg0).name;
return addHeapObject(ret);
};
imports.wbg.__wbg_toString_d0cefe4046ecb265 = function(arg0) {
imports.wbg.__wbg_toString_a44236e90224e279 = function(arg0) {
const ret = getObject(arg0).toString();
return addHeapObject(ret);
};
imports.wbg.__wbg_isSafeInteger_c38b0a16d0c7cef7 = function(arg0) {
imports.wbg.__wbg_isSafeInteger_f93fde0dca9820f8 = function(arg0) {
const ret = Number.isSafeInteger(getObject(arg0));
return ret;
};
imports.wbg.__wbg_entries_6d727b73ee02b7ce = function(arg0) {
imports.wbg.__wbg_entries_9e2e2aa45aa5094a = function(arg0) {
const ret = Object.entries(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_is_c74aa9bb973d6109 = function(arg0, arg1) {
imports.wbg.__wbg_is_ff7acd231c75c0e4 = function(arg0, arg1) {
const ret = Object.is(getObject(arg0), getObject(arg1));
return ret;
};
imports.wbg.__wbg_resolve_a3252b2860f0a09e = function(arg0) {
imports.wbg.__wbg_resolve_6e1c6553a82f85b7 = function(arg0) {
const ret = Promise.resolve(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_then_89e1c559530b85cf = function(arg0, arg1) {
imports.wbg.__wbg_then_3ab08cd4fbb91ae9 = function(arg0, arg1) {
const ret = getObject(arg0).then(getObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_then_1bbc9edafd859b06 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_then_8371cc12cfedc5a2 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_buffer_344d9b41efe96da7 = function(arg0) {
imports.wbg.__wbg_buffer_a448f833075b71ba = function(arg0) {
const ret = getObject(arg0).buffer;
return addHeapObject(ret);
};
imports.wbg.__wbg_new_d8a000788389a31e = function(arg0) {
imports.wbg.__wbg_new_8f67e318f15d7254 = function(arg0) {
const ret = new Uint8Array(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_set_dcfd613a3420f908 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_2357bf09366ee480 = function(arg0, arg1, arg2) {
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
};
imports.wbg.__wbg_length_a5587d6cd79ab197 = function(arg0) {
imports.wbg.__wbg_length_1d25fa9e4ac21ce7 = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbg_instanceof_Uint8Array_19e6f142a5e7e1e1 = function(arg0) {
imports.wbg.__wbg_instanceof_Uint8Array_bced6f43aed8c1aa = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Uint8Array;
@ -951,7 +951,7 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_set_40f7786a25a9cc7e = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_set_759f75cd92b612d2 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
return ret;
}, arguments) };
@ -969,16 +969,16 @@ function __wbg_get_imports() {
const ret = wasm.memory;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1235 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 558, __wbg_adapter_38);
imports.wbg.__wbindgen_closure_wrapper1222 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 541, __wbg_adapter_38);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1369 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 624, __wbg_adapter_41);
imports.wbg.__wbindgen_closure_wrapper1337 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 593, __wbg_adapter_41);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1450 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 655, __wbg_adapter_44);
imports.wbg.__wbindgen_closure_wrapper1417 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 622, __wbg_adapter_44);
return addHeapObject(ret);
};

View file

@ -232,19 +232,19 @@ function addBorrowedObject(obj) {
}
function __wbg_adapter_48(arg0, arg1, arg2) {
try {
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h3592199ac636c7ab(arg0, arg1, addBorrowedObject(arg2));
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hcd8161c254227fe4(arg0, arg1, addBorrowedObject(arg2));
} finally {
heap[stack_pointer++] = undefined;
}
}
function __wbg_adapter_51(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h71282a39cf9f54cc(arg0, arg1, addHeapObject(arg2));
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hbb91bcb76d7d57c6(arg0, arg1, addHeapObject(arg2));
}
function __wbg_adapter_54(arg0, arg1, arg2) {
try {
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h0e38a66b2b075f9c(arg0, arg1, addBorrowedObject(arg2));
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8e106c18de4fadc7(arg0, arg1, addBorrowedObject(arg2));
} finally {
heap[stack_pointer++] = undefined;
}
@ -346,6 +346,15 @@ function __wbg_get_imports() {
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbindgen_cb_drop = function(arg0) {
const obj = takeObject(arg0).original;
if (obj.cnt-- == 1) {
obj.a = 0;
return true;
}
const ret = false;
return ret;
};
imports.wbg.__wbindgen_boolean_get = function(arg0) {
const v = getObject(arg0);
const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2;
@ -390,23 +399,14 @@ function __wbg_get_imports() {
const ret = getObject(arg0) === undefined;
return ret;
};
imports.wbg.__wbindgen_cb_drop = function(arg0) {
const obj = takeObject(arg0).original;
if (obj.cnt-- == 1) {
obj.a = 0;
return true;
}
const ret = false;
return ret;
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_error_new = function(arg0, arg1) {
const ret = new Error(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbg_setlistenerid_3183aae8fa5840fb = function(arg0, arg1) {
getObject(arg0).__yew_listener_id = arg1 >>> 0;
};
@ -464,10 +464,10 @@ function __wbg_get_imports() {
imports.wbg.__wbg_set_20cbc34131e76824 = function(arg0, arg1, arg2) {
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
};
imports.wbg.__wbg_queueMicrotask_e5949c35d772a669 = function(arg0) {
imports.wbg.__wbg_queueMicrotask_4d890031a6a5a50c = function(arg0) {
queueMicrotask(getObject(arg0));
};
imports.wbg.__wbg_queueMicrotask_2be8b97a81fe4d00 = function(arg0) {
imports.wbg.__wbg_queueMicrotask_adae4bc085237231 = function(arg0) {
const ret = getObject(arg0).queueMicrotask;
return addHeapObject(ret);
};
@ -507,31 +507,31 @@ function __wbg_get_imports() {
wasm.__wbindgen_free(arg0, arg1 * 4, 4);
console.warn(...v0);
};
imports.wbg.__wbg_body_11da0c1aa9610cb3 = function(arg0) {
imports.wbg.__wbg_body_64abc9aba1891e91 = function(arg0) {
const ret = getObject(arg0).body;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_createElement_9ce3fdea8322ff34 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_createElement_fdd5c113cb84539e = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).createElement(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_createElementNS_6a08d8f33e767e18 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_createElementNS_524b05a6070757b6 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
const ret = getObject(arg0).createElementNS(arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_createTextNode_01a7250c5ca46b04 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_createTextNode_7ff0c034b2855f66 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).createTextNode(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_getElementById_328f8c4a5bb51ba8 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_getElementById_65b9547a428b5eb4 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_querySelector_391afe271b8236d5 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_querySelector_c72dce5ac4b6bc3e = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).querySelector(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Window_cde2416cf5126a72 = function(arg0) {
imports.wbg.__wbg_instanceof_Window_3e5cd1f48c152d01 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Window;
@ -541,35 +541,35 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_document_183cf1eecfdbffee = function(arg0) {
imports.wbg.__wbg_document_d609202d16c38224 = function(arg0) {
const ret = getObject(arg0).document;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_location_61ca61017633c753 = function(arg0) {
imports.wbg.__wbg_location_176c34e89c2c9d80 = function(arg0) {
const ret = getObject(arg0).location;
return addHeapObject(ret);
};
imports.wbg.__wbg_history_56dc869560201113 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_history_80998b7456bf367e = function() { return handleError(function (arg0) {
const ret = getObject(arg0).history;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_navigator_7078da62d92ff5ad = function(arg0) {
imports.wbg.__wbg_navigator_96ba491902f8f083 = function(arg0) {
const ret = getObject(arg0).navigator;
return addHeapObject(ret);
};
imports.wbg.__wbg_localStorage_e11f72e996a4f5d9 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_localStorage_8c507fd281456944 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).localStorage;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_sessionStorage_071949dc646bfd35 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_sessionStorage_adb12b0c8ea06c48 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).sessionStorage;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_fetch_8cebc656dc6b11b1 = function(arg0, arg1) {
imports.wbg.__wbg_fetch_6c415b3a07763878 = function(arg0, arg1) {
const ret = getObject(arg0).fetch(getObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_instanceof_Element_6c7af07f5e6c8d69 = function(arg0) {
imports.wbg.__wbg_instanceof_Element_3f326a19cc457941 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Element;
@ -579,38 +579,38 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_namespaceURI_2dd94d0147ffddf2 = function(arg0, arg1) {
imports.wbg.__wbg_namespaceURI_7cc7ef157e398356 = function(arg0, arg1) {
const ret = getObject(arg1).namespaceURI;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_classList_7fd39dc155235d8a = function(arg0) {
imports.wbg.__wbg_classList_82893a9100db6428 = function(arg0) {
const ret = getObject(arg0).classList;
return addHeapObject(ret);
};
imports.wbg.__wbg_setinnerHTML_b88bf159b62c2334 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setinnerHTML_ce0d6527ce4086f2 = function(arg0, arg1, arg2) {
getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_outerHTML_72dcf3aa34725f10 = function(arg0, arg1) {
imports.wbg.__wbg_outerHTML_b5a8d952b5615778 = function(arg0, arg1) {
const ret = getObject(arg1).outerHTML;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_children_af5a3246832628b1 = function(arg0) {
imports.wbg.__wbg_children_990f38c4f4d5c721 = function(arg0) {
const ret = getObject(arg0).children;
return addHeapObject(ret);
};
imports.wbg.__wbg_removeAttribute_dbd76981f9bb9f59 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_removeAttribute_2e200daefb9f3ed4 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeAttribute(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setAttribute_aebcae2169f2f869 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_setAttribute_e7b72a5e7cfcb5a3 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlElement_d9fe655ad4f1046c = function(arg0) {
imports.wbg.__wbg_instanceof_HtmlElement_55a0f0f0f0f0118e = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLElement;
@ -620,86 +620,86 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_focus_bab0841297cb9142 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_focus_6d3d2b6776d06f7f = function() { return handleError(function (arg0) {
getObject(arg0).focus();
}, arguments) };
imports.wbg.__wbg_get_be3f61d062825ba1 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_get_41904a8f394b5093 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).get(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_credentials_6a08cfc972615f5c = function(arg0) {
imports.wbg.__wbg_credentials_cef3aa4d1e919496 = function(arg0) {
const ret = getObject(arg0).credentials;
return addHeapObject(ret);
};
imports.wbg.__wbg_getItem_c81cd3ae30cd579a = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_getItem_5395a7e200c31e89 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_removeItem_58a487fe7fc070f0 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_removeItem_c84f914587f36b1a = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setItem_fe04f524052a3839 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_setItem_3786c4c8dd0c9bd0 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_addEventListener_51709b9747ad8980 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_addEventListener_374cbfd2bbc19ccf = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
}, arguments) };
imports.wbg.__wbg_removeEventListener_5b1e762a7951280a = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_removeEventListener_9ece7e86d1135657 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
}, arguments) };
imports.wbg.__wbg_state_78eaa7b6ff3123a0 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_state_ba77b2c3ee29c912 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).state;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_pushState_8eaca41f86b13910 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
imports.wbg.__wbg_pushState_e159043fce8f87bc = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
}, arguments) };
imports.wbg.__wbg_href_92490614763f3f7c = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_href_160af2ae1328d7b7 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_sethref_2c377515f8ddd13a = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_sethref_90b000c8b01f96b1 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
}, arguments) };
imports.wbg.__wbg_pathname_cd5a90c8f3ab524a = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_pathname_1ab7e82aaa4511ff = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_search_08fbba2309a249da = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_search_9f7ca8896c2d0804 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_hash_ced9ee31706e591d = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_hash_be2940ca236b5efc = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_replace_4f50b38e38ea7fd6 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_replace_c73ceee21ffa44ab = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).replace(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_headers_4711243cf3bffca0 = function(arg0) {
imports.wbg.__wbg_headers_d135d2bb8cc60413 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithstrandinit_29038da14d09e330 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_newwithstrandinit_f581dff0d19a8b03 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Response_944e2745b5db71f5 = function(arg0) {
imports.wbg.__wbg_instanceof_Response_4c3b1446206114d1 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Response;
@ -709,57 +709,57 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_status_7841bb47be2a8f16 = function(arg0) {
imports.wbg.__wbg_status_d6d47ad2837621eb = function(arg0) {
const ret = getObject(arg0).status;
return ret;
};
imports.wbg.__wbg_headers_ea7ef583d1564b08 = function(arg0) {
imports.wbg.__wbg_headers_24def508a7518df9 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_json_7f96c90903ae4155 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_json_34535d9848f043eb = function() { return handleError(function (arg0) {
const ret = getObject(arg0).json();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_parentNode_e1c214fc3f362af0 = function(arg0) {
imports.wbg.__wbg_parentNode_92a7017b3a4fad43 = function(arg0) {
const ret = getObject(arg0).parentNode;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_parentElement_592cb54944d3d002 = function(arg0) {
imports.wbg.__wbg_parentElement_72e144c2e8d9e0b5 = function(arg0) {
const ret = getObject(arg0).parentElement;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_lastChild_b17b3c7498d25bd7 = function(arg0) {
imports.wbg.__wbg_lastChild_a62e3fbaab87f734 = function(arg0) {
const ret = getObject(arg0).lastChild;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_nextSibling_d029031876ed1b1b = function(arg0) {
imports.wbg.__wbg_nextSibling_bafccd3347d24543 = function(arg0) {
const ret = getObject(arg0).nextSibling;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_setnodeValue_321840a6762ab272 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setnodeValue_630c6470d05b600e = function(arg0, arg1, arg2) {
getObject(arg0).nodeValue = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_textContent_d69d000f6081b514 = function(arg0, arg1) {
imports.wbg.__wbg_textContent_2f37235e13f8484b = function(arg0, arg1) {
const ret = getObject(arg1).textContent;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_appendChild_2e6a6c9d1f0d443d = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_appendChild_d30e6b83791d04c0 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).appendChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_insertBefore_bdaeec8969497673 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_insertBefore_726c1640c419e940 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).insertBefore(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_removeChild_a63022ebbfa6ebf5 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_removeChild_942eb9c02243d84d = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).removeChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_ShadowRoot_f85f709c953844de = function(arg0) {
imports.wbg.__wbg_instanceof_ShadowRoot_0bd39e89ab117f86 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof ShadowRoot;
@ -769,63 +769,63 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_host_73c8e95bf9b31ccd = function(arg0) {
imports.wbg.__wbg_host_09eee5e3d9cf59a1 = function(arg0) {
const ret = getObject(arg0).host;
return addHeapObject(ret);
};
imports.wbg.__wbg_getClientExtensionResults_d4b9b581db88e947 = function(arg0) {
imports.wbg.__wbg_getClientExtensionResults_8da1aa123f3b7c0b = function(arg0) {
const ret = getObject(arg0).getClientExtensionResults();
return addHeapObject(ret);
};
imports.wbg.__wbg_log_7811587c4c6d2844 = function(arg0) {
imports.wbg.__wbg_log_a4530b4fe289336f = function(arg0) {
console.log(getObject(arg0));
};
imports.wbg.__wbg_add_dc5c00591ed65268 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_add_e0f3c5b6e421c311 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_remove_9517d3139a6031f1 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_remove_c6ba26a0a6906129 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_href_7f944b48b612250e = function(arg0, arg1) {
imports.wbg.__wbg_href_e9aac3826080dcaa = function(arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_pathname_a83d8f2ebefa6791 = function(arg0, arg1) {
imports.wbg.__wbg_pathname_aeafa820be91c325 = function(arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_search_8c5f74fa2d11377e = function(arg0, arg1) {
imports.wbg.__wbg_search_f6e95882a48d3f69 = function(arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_hash_f468e7d38a21a76a = function(arg0, arg1) {
imports.wbg.__wbg_hash_0087751acddc8f2a = function(arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_sethash_7c3032584865b2bd = function(arg0, arg1, arg2) {
imports.wbg.__wbg_sethash_bfc9db317a77305c = function(arg0, arg1, arg2) {
getObject(arg0).hash = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_new_d7cd05d9de7d4000 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_new_9e08fd37c1c53142 = function() { return handleError(function (arg0, arg1) {
const ret = new URL(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_newwithbase_604e8dfd42d25665 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_newwithbase_f4989aa5bbd5cc29 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlInputElement_8f81a6600ceb1918 = function(arg0) {
imports.wbg.__wbg_instanceof_HtmlInputElement_e7869aaef9cbb0e6 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLInputElement;
@ -835,149 +835,149 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_checked_1ce2f33e2ed42870 = function(arg0) {
imports.wbg.__wbg_checked_f46acdc11342a4bd = function(arg0) {
const ret = getObject(arg0).checked;
return ret;
};
imports.wbg.__wbg_setchecked_5757666239434ecd = function(arg0, arg1) {
imports.wbg.__wbg_setchecked_c1d5c3726082e274 = function(arg0, arg1) {
getObject(arg0).checked = arg1 !== 0;
};
imports.wbg.__wbg_value_5e860795f53217cd = function(arg0, arg1) {
imports.wbg.__wbg_value_e024243a9dae20bc = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_7d187f6cc23d8192 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setvalue_5b3442ff620b4a5d = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_bubbles_c27af65192eb3569 = function(arg0) {
imports.wbg.__wbg_bubbles_f1cdd0584446cad0 = function(arg0) {
const ret = getObject(arg0).bubbles;
return ret;
};
imports.wbg.__wbg_cancelBubble_ee3f70328e901584 = function(arg0) {
imports.wbg.__wbg_cancelBubble_976cfdf7ac449a6c = function(arg0) {
const ret = getObject(arg0).cancelBubble;
return ret;
};
imports.wbg.__wbg_composedPath_ee37eece046b69a2 = function(arg0) {
imports.wbg.__wbg_composedPath_12a068e57a98cf90 = function(arg0) {
const ret = getObject(arg0).composedPath();
return addHeapObject(ret);
};
imports.wbg.__wbg_preventDefault_9299867e06da6909 = function(arg0) {
imports.wbg.__wbg_preventDefault_7f821f72e7c6b5d4 = function(arg0) {
getObject(arg0).preventDefault();
};
imports.wbg.__wbg_get_9470c6584bbde430 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_get_0231cdd369e04a1d = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_set_2912c891505cbc22 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_set_27f236f6d7a28c29 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_href_2777cc28ba3aac82 = function(arg0, arg1) {
imports.wbg.__wbg_href_f21dc804d4da134a = function(arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_value_539db729f551be3a = function(arg0, arg1) {
imports.wbg.__wbg_value_57e57170f6952449 = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_15231c60278dee22 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setvalue_a11f3069fd7a1805 = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_get_4a9aa5157afeb382 = function(arg0, arg1) {
imports.wbg.__wbg_get_f01601b5a68d10e3 = function(arg0, arg1) {
const ret = getObject(arg0)[arg1 >>> 0];
return addHeapObject(ret);
};
imports.wbg.__wbg_length_cace2e0b3ddc0502 = function(arg0) {
imports.wbg.__wbg_length_1009b1af0c481d7b = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbg_new_08236689f0afb357 = function() {
imports.wbg.__wbg_new_ffc6d4d085022169 = function() {
const ret = new Array();
return addHeapObject(ret);
};
imports.wbg.__wbg_newnoargs_ccdcae30fd002262 = function(arg0, arg1) {
imports.wbg.__wbg_newnoargs_c62ea9419c21fbac = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_new_1b94180eeb48f2a2 = function() {
imports.wbg.__wbg_new_bfd4534b584a9593 = function() {
const ret = new Map();
return addHeapObject(ret);
};
imports.wbg.__wbg_next_15da6a3df9290720 = function(arg0) {
imports.wbg.__wbg_next_9b877f231f476d01 = function(arg0) {
const ret = getObject(arg0).next;
return addHeapObject(ret);
};
imports.wbg.__wbg_next_1989a20442400aaa = function() { return handleError(function (arg0) {
imports.wbg.__wbg_next_6529ee0cca8d57ed = function() { return handleError(function (arg0) {
const ret = getObject(arg0).next();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_done_bc26bf4ada718266 = function(arg0) {
imports.wbg.__wbg_done_5fe336b092d60cf2 = function(arg0) {
const ret = getObject(arg0).done;
return ret;
};
imports.wbg.__wbg_value_0570714ff7d75f35 = function(arg0) {
imports.wbg.__wbg_value_0c248a78fdc8e19f = function(arg0) {
const ret = getObject(arg0).value;
return addHeapObject(ret);
};
imports.wbg.__wbg_iterator_7ee1a391d310f8e4 = function() {
imports.wbg.__wbg_iterator_db7ca081358d4fb2 = function() {
const ret = Symbol.iterator;
return addHeapObject(ret);
};
imports.wbg.__wbg_get_2aff440840bb6202 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_get_7b48513de5dc5ea4 = function() { return handleError(function (arg0, arg1) {
const ret = Reflect.get(getObject(arg0), getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_call_669127b9d730c650 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_call_90c26b09837aba1c = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).call(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_new_c728d68b8b34487e = function() {
imports.wbg.__wbg_new_9fb8d994e1c0aaac = function() {
const ret = new Object();
return addHeapObject(ret);
};
imports.wbg.__wbg_self_3fad056edded10bd = function() { return handleError(function () {
imports.wbg.__wbg_self_f0e34d89f33b99fd = function() { return handleError(function () {
const ret = self.self;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_window_a4f46c98a61d4089 = function() { return handleError(function () {
imports.wbg.__wbg_window_d3b084224f4774d7 = function() { return handleError(function () {
const ret = window.window;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_globalThis_17eff828815f7d84 = function() { return handleError(function () {
imports.wbg.__wbg_globalThis_9caa27ff917c6860 = function() { return handleError(function () {
const ret = globalThis.globalThis;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_global_46f939f6541643c5 = function() { return handleError(function () {
imports.wbg.__wbg_global_35dfdd59a4da3e74 = function() { return handleError(function () {
const ret = global.global;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_set_0ac78a2bc07da03c = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_f2740edb12e318cd = function(arg0, arg1, arg2) {
getObject(arg0)[arg1 >>> 0] = takeObject(arg2);
};
imports.wbg.__wbg_from_ba72c50feaf1d8c0 = function(arg0) {
imports.wbg.__wbg_from_71add2e723d1f1b2 = function(arg0) {
const ret = Array.from(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_isArray_38525be7442aa21e = function(arg0) {
imports.wbg.__wbg_isArray_74fb723e24f76012 = function(arg0) {
const ret = Array.isArray(getObject(arg0));
return ret;
};
imports.wbg.__wbg_push_fd3233d09cf81821 = function(arg0, arg1) {
imports.wbg.__wbg_push_901f3914205d44de = function(arg0, arg1) {
const ret = getObject(arg0).push(getObject(arg1));
return ret;
};
imports.wbg.__wbg_instanceof_ArrayBuffer_c7cc317e5c29cc0d = function(arg0) {
imports.wbg.__wbg_instanceof_ArrayBuffer_e7d53d51371448e2 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof ArrayBuffer;
@ -987,7 +987,7 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_Error_9f5881c3c4149389 = function(arg0) {
imports.wbg.__wbg_instanceof_Error_31ca8d97f188bfbc = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Error;
@ -997,66 +997,66 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_message_35f9b952e1b922e2 = function(arg0) {
imports.wbg.__wbg_message_55b9ea8030688597 = function(arg0) {
const ret = getObject(arg0).message;
return addHeapObject(ret);
};
imports.wbg.__wbg_name_e1152a59269f79e5 = function(arg0) {
imports.wbg.__wbg_name_e5eede664187fed6 = function(arg0) {
const ret = getObject(arg0).name;
return addHeapObject(ret);
};
imports.wbg.__wbg_toString_d0cefe4046ecb265 = function(arg0) {
imports.wbg.__wbg_toString_a44236e90224e279 = function(arg0) {
const ret = getObject(arg0).toString();
return addHeapObject(ret);
};
imports.wbg.__wbg_set_3355b9f2d3092e3b = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_d257c6f2da008627 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_isSafeInteger_c38b0a16d0c7cef7 = function(arg0) {
imports.wbg.__wbg_isSafeInteger_f93fde0dca9820f8 = function(arg0) {
const ret = Number.isSafeInteger(getObject(arg0));
return ret;
};
imports.wbg.__wbg_entries_6d727b73ee02b7ce = function(arg0) {
imports.wbg.__wbg_entries_9e2e2aa45aa5094a = function(arg0) {
const ret = Object.entries(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_is_c74aa9bb973d6109 = function(arg0, arg1) {
imports.wbg.__wbg_is_ff7acd231c75c0e4 = function(arg0, arg1) {
const ret = Object.is(getObject(arg0), getObject(arg1));
return ret;
};
imports.wbg.__wbg_resolve_a3252b2860f0a09e = function(arg0) {
imports.wbg.__wbg_resolve_6e1c6553a82f85b7 = function(arg0) {
const ret = Promise.resolve(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_then_89e1c559530b85cf = function(arg0, arg1) {
imports.wbg.__wbg_then_3ab08cd4fbb91ae9 = function(arg0, arg1) {
const ret = getObject(arg0).then(getObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_then_1bbc9edafd859b06 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_then_8371cc12cfedc5a2 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_buffer_344d9b41efe96da7 = function(arg0) {
imports.wbg.__wbg_buffer_a448f833075b71ba = function(arg0) {
const ret = getObject(arg0).buffer;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithbyteoffsetandlength_2dc04d99088b15e3 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_newwithbyteoffsetandlength_d0482f893617af71 = function(arg0, arg1, arg2) {
const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
return addHeapObject(ret);
};
imports.wbg.__wbg_new_d8a000788389a31e = function(arg0) {
imports.wbg.__wbg_new_8f67e318f15d7254 = function(arg0) {
const ret = new Uint8Array(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_set_dcfd613a3420f908 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_2357bf09366ee480 = function(arg0, arg1, arg2) {
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
};
imports.wbg.__wbg_length_a5587d6cd79ab197 = function(arg0) {
imports.wbg.__wbg_length_1d25fa9e4ac21ce7 = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbg_instanceof_Uint8Array_19e6f142a5e7e1e1 = function(arg0) {
imports.wbg.__wbg_instanceof_Uint8Array_bced6f43aed8c1aa = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Uint8Array;
@ -1066,11 +1066,11 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_set_40f7786a25a9cc7e = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_set_759f75cd92b612d2 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
return ret;
}, arguments) };
imports.wbg.__wbg_stringify_4039297315a25b00 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_stringify_e1b19966d964d242 = function() { return handleError(function (arg0) {
const ret = JSON.stringify(getObject(arg0));
return addHeapObject(ret);
}, arguments) };
@ -1094,16 +1094,16 @@ function __wbg_get_imports() {
const ret = wasm.memory;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1388 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 488, __wbg_adapter_48);
imports.wbg.__wbindgen_closure_wrapper1297 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 459, __wbg_adapter_48);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1773 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 630, __wbg_adapter_51);
imports.wbg.__wbindgen_closure_wrapper1737 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 601, __wbg_adapter_51);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1855 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 661, __wbg_adapter_54);
imports.wbg.__wbindgen_closure_wrapper1822 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 632, __wbg_adapter_54);
return addHeapObject(ret);
};

View file

@ -225,7 +225,7 @@ function makeMutClosure(arg0, arg1, dtor, f) {
return real;
}
function __wbg_adapter_48(arg0, arg1) {
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h4b3f7f6f56bc064a(arg0, arg1);
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h0c62d2840bb83f65(arg0, arg1);
}
let stack_pointer = 128;
@ -237,19 +237,19 @@ function addBorrowedObject(obj) {
}
function __wbg_adapter_51(arg0, arg1, arg2) {
try {
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha7af6bbd80504275(arg0, arg1, addBorrowedObject(arg2));
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h703c5e695d9d8aa0(arg0, arg1, addBorrowedObject(arg2));
} finally {
heap[stack_pointer++] = undefined;
}
}
function __wbg_adapter_54(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h71282a39cf9f54cc(arg0, arg1, addHeapObject(arg2));
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hbb91bcb76d7d57c6(arg0, arg1, addHeapObject(arg2));
}
function __wbg_adapter_57(arg0, arg1, arg2) {
try {
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__he72980a19bbd8d74(arg0, arg1, addBorrowedObject(arg2));
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h16a1b64144cde668(arg0, arg1, addBorrowedObject(arg2));
} finally {
heap[stack_pointer++] = undefined;
}
@ -403,14 +403,14 @@ function __wbg_get_imports() {
const ret = false;
return ret;
};
imports.wbg.__wbindgen_error_new = function(arg0, arg1) {
const ret = new Error(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_error_new = function(arg0, arg1) {
const ret = new Error(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_clearTimeout_541ac0980ffcef74 = function(arg0) {
const ret = clearTimeout(takeObject(arg0));
return addHeapObject(ret);
@ -476,10 +476,10 @@ function __wbg_get_imports() {
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
}
};
imports.wbg.__wbg_queueMicrotask_e5949c35d772a669 = function(arg0) {
imports.wbg.__wbg_queueMicrotask_4d890031a6a5a50c = function(arg0) {
queueMicrotask(getObject(arg0));
};
imports.wbg.__wbg_queueMicrotask_2be8b97a81fe4d00 = function(arg0) {
imports.wbg.__wbg_queueMicrotask_adae4bc085237231 = function(arg0) {
const ret = getObject(arg0).queueMicrotask;
return addHeapObject(ret);
};
@ -520,38 +520,38 @@ function __wbg_get_imports() {
imports.wbg.__wbg_set_20cbc34131e76824 = function(arg0, arg1, arg2) {
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
};
imports.wbg.__wbg_documentURI_0b154b59e1e400a6 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_documentURI_5d5237c96f11d7e6 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).documentURI;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_body_11da0c1aa9610cb3 = function(arg0) {
imports.wbg.__wbg_body_64abc9aba1891e91 = function(arg0) {
const ret = getObject(arg0).body;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_createElement_9ce3fdea8322ff34 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_createElement_fdd5c113cb84539e = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).createElement(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_createElementNS_6a08d8f33e767e18 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_createElementNS_524b05a6070757b6 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
const ret = getObject(arg0).createElementNS(arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_createTextNode_01a7250c5ca46b04 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_createTextNode_7ff0c034b2855f66 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).createTextNode(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_getElementById_328f8c4a5bb51ba8 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_getElementById_65b9547a428b5eb4 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_querySelector_391afe271b8236d5 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_querySelector_c72dce5ac4b6bc3e = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).querySelector(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Window_cde2416cf5126a72 = function(arg0) {
imports.wbg.__wbg_instanceof_Window_3e5cd1f48c152d01 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Window;
@ -561,35 +561,35 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_document_183cf1eecfdbffee = function(arg0) {
imports.wbg.__wbg_document_d609202d16c38224 = function(arg0) {
const ret = getObject(arg0).document;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_location_61ca61017633c753 = function(arg0) {
imports.wbg.__wbg_location_176c34e89c2c9d80 = function(arg0) {
const ret = getObject(arg0).location;
return addHeapObject(ret);
};
imports.wbg.__wbg_history_56dc869560201113 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_history_80998b7456bf367e = function() { return handleError(function (arg0) {
const ret = getObject(arg0).history;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_navigator_7078da62d92ff5ad = function(arg0) {
imports.wbg.__wbg_navigator_96ba491902f8f083 = function(arg0) {
const ret = getObject(arg0).navigator;
return addHeapObject(ret);
};
imports.wbg.__wbg_localStorage_e11f72e996a4f5d9 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_localStorage_8c507fd281456944 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).localStorage;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_sessionStorage_071949dc646bfd35 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_sessionStorage_adb12b0c8ea06c48 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).sessionStorage;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_fetch_8cebc656dc6b11b1 = function(arg0, arg1) {
imports.wbg.__wbg_fetch_6c415b3a07763878 = function(arg0, arg1) {
const ret = getObject(arg0).fetch(getObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_instanceof_Element_6c7af07f5e6c8d69 = function(arg0) {
imports.wbg.__wbg_instanceof_Element_3f326a19cc457941 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Element;
@ -599,38 +599,38 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_namespaceURI_2dd94d0147ffddf2 = function(arg0, arg1) {
imports.wbg.__wbg_namespaceURI_7cc7ef157e398356 = function(arg0, arg1) {
const ret = getObject(arg1).namespaceURI;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_classList_7fd39dc155235d8a = function(arg0) {
imports.wbg.__wbg_classList_82893a9100db6428 = function(arg0) {
const ret = getObject(arg0).classList;
return addHeapObject(ret);
};
imports.wbg.__wbg_setinnerHTML_b88bf159b62c2334 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setinnerHTML_ce0d6527ce4086f2 = function(arg0, arg1, arg2) {
getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_outerHTML_72dcf3aa34725f10 = function(arg0, arg1) {
imports.wbg.__wbg_outerHTML_b5a8d952b5615778 = function(arg0, arg1) {
const ret = getObject(arg1).outerHTML;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_children_af5a3246832628b1 = function(arg0) {
imports.wbg.__wbg_children_990f38c4f4d5c721 = function(arg0) {
const ret = getObject(arg0).children;
return addHeapObject(ret);
};
imports.wbg.__wbg_removeAttribute_dbd76981f9bb9f59 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_removeAttribute_2e200daefb9f3ed4 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeAttribute(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setAttribute_aebcae2169f2f869 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_setAttribute_e7b72a5e7cfcb5a3 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlElement_d9fe655ad4f1046c = function(arg0) {
imports.wbg.__wbg_instanceof_HtmlElement_55a0f0f0f0f0118e = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLElement;
@ -640,193 +640,137 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_focus_bab0841297cb9142 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_focus_6d3d2b6776d06f7f = function() { return handleError(function (arg0) {
getObject(arg0).focus();
}, arguments) };
imports.wbg.__wbg_credentials_6a08cfc972615f5c = function(arg0) {
imports.wbg.__wbg_credentials_cef3aa4d1e919496 = function(arg0) {
const ret = getObject(arg0).credentials;
return addHeapObject(ret);
};
imports.wbg.__wbg_getItem_c81cd3ae30cd579a = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_getItem_5395a7e200c31e89 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_removeItem_58a487fe7fc070f0 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_removeItem_c84f914587f36b1a = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setItem_fe04f524052a3839 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_setItem_3786c4c8dd0c9bd0 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_href_7f944b48b612250e = function(arg0, arg1) {
imports.wbg.__wbg_href_e9aac3826080dcaa = function(arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_pathname_a83d8f2ebefa6791 = function(arg0, arg1) {
imports.wbg.__wbg_pathname_aeafa820be91c325 = function(arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_search_8c5f74fa2d11377e = function(arg0, arg1) {
imports.wbg.__wbg_search_f6e95882a48d3f69 = function(arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setsearch_a168105ad9dbdb8b = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setsearch_4f7d084e0d811add = function(arg0, arg1, arg2) {
getObject(arg0).search = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_hash_f468e7d38a21a76a = function(arg0, arg1) {
imports.wbg.__wbg_hash_0087751acddc8f2a = function(arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_sethash_7c3032584865b2bd = function(arg0, arg1, arg2) {
imports.wbg.__wbg_sethash_bfc9db317a77305c = function(arg0, arg1, arg2) {
getObject(arg0).hash = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_new_d7cd05d9de7d4000 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_new_9e08fd37c1c53142 = function() { return handleError(function (arg0, arg1) {
const ret = new URL(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_newwithbase_604e8dfd42d25665 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_newwithbase_f4989aa5bbd5cc29 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_href_2777cc28ba3aac82 = function(arg0, arg1) {
imports.wbg.__wbg_href_f21dc804d4da134a = function(arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_value_539db729f551be3a = function(arg0, arg1) {
imports.wbg.__wbg_value_57e57170f6952449 = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_15231c60278dee22 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setvalue_a11f3069fd7a1805 = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_target_6efb4504c149139f = function(arg0) {
imports.wbg.__wbg_target_52ddf6955f636bf5 = function(arg0) {
const ret = getObject(arg0).target;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_bubbles_c27af65192eb3569 = function(arg0) {
imports.wbg.__wbg_bubbles_f1cdd0584446cad0 = function(arg0) {
const ret = getObject(arg0).bubbles;
return ret;
};
imports.wbg.__wbg_cancelBubble_ee3f70328e901584 = function(arg0) {
imports.wbg.__wbg_cancelBubble_976cfdf7ac449a6c = function(arg0) {
const ret = getObject(arg0).cancelBubble;
return ret;
};
imports.wbg.__wbg_composedPath_ee37eece046b69a2 = function(arg0) {
imports.wbg.__wbg_composedPath_12a068e57a98cf90 = function(arg0) {
const ret = getObject(arg0).composedPath();
return addHeapObject(ret);
};
imports.wbg.__wbg_preventDefault_9299867e06da6909 = function(arg0) {
imports.wbg.__wbg_preventDefault_7f821f72e7c6b5d4 = function(arg0) {
getObject(arg0).preventDefault();
};
imports.wbg.__wbg_get_9470c6584bbde430 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
imports.wbg.__wbg_get_0231cdd369e04a1d = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_set_2912c891505cbc22 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
imports.wbg.__wbg_set_27f236f6d7a28c29 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_getClientExtensionResults_d4b9b581db88e947 = function(arg0) {
imports.wbg.__wbg_getClientExtensionResults_8da1aa123f3b7c0b = function(arg0) {
const ret = getObject(arg0).getClientExtensionResults();
return addHeapObject(ret);
};
imports.wbg.__wbg_addEventListener_51709b9747ad8980 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
}, arguments) };
imports.wbg.__wbg_removeEventListener_5b1e762a7951280a = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
}, arguments) };
imports.wbg.__wbg_state_78eaa7b6ff3123a0 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).state;
imports.wbg.__wbg_create_413706d5496ca07c = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).create(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_pushState_8eaca41f86b13910 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
imports.wbg.__wbg_add_e0f3c5b6e421c311 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_href_92490614763f3f7c = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
imports.wbg.__wbg_remove_c6ba26a0a6906129 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_sethref_2c377515f8ddd13a = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
imports.wbg.__wbg_newwithform_f67de494d7d454b2 = function() { return handleError(function (arg0) {
const ret = new FormData(getObject(arg0));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_pathname_cd5a90c8f3ab524a = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_search_08fbba2309a249da = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_hash_ced9ee31706e591d = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_headers_4711243cf3bffca0 = function(arg0) {
const ret = getObject(arg0).headers;
imports.wbg.__wbg_get_d5bbacfdbebebc6e = function(arg0, arg1, arg2) {
const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithstrandinit_29038da14d09e330 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Response_944e2745b5db71f5 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Response;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_status_7841bb47be2a8f16 = function(arg0) {
const ret = getObject(arg0).status;
return ret;
};
imports.wbg.__wbg_headers_ea7ef583d1564b08 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_json_7f96c90903ae4155 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).json();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlInputElement_8f81a6600ceb1918 = function(arg0) {
imports.wbg.__wbg_instanceof_HtmlInputElement_e7869aaef9cbb0e6 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLInputElement;
@ -836,38 +780,94 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_setchecked_5757666239434ecd = function(arg0, arg1) {
imports.wbg.__wbg_setchecked_c1d5c3726082e274 = function(arg0, arg1) {
getObject(arg0).checked = arg1 !== 0;
};
imports.wbg.__wbg_value_5e860795f53217cd = function(arg0, arg1) {
imports.wbg.__wbg_value_e024243a9dae20bc = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_7d187f6cc23d8192 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setvalue_5b3442ff620b4a5d = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_create_3e99c3ed46cd9f00 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).create(getObject(arg1));
imports.wbg.__wbg_addEventListener_374cbfd2bbc19ccf = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
}, arguments) };
imports.wbg.__wbg_removeEventListener_9ece7e86d1135657 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
}, arguments) };
imports.wbg.__wbg_state_ba77b2c3ee29c912 = function() { return handleError(function (arg0) {
const ret = getObject(arg0).state;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_add_dc5c00591ed65268 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
imports.wbg.__wbg_pushState_e159043fce8f87bc = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
}, arguments) };
imports.wbg.__wbg_remove_9517d3139a6031f1 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
imports.wbg.__wbg_href_160af2ae1328d7b7 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).href;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_newwithform_e7fc7c06976f3c8f = function() { return handleError(function (arg0) {
const ret = new FormData(getObject(arg0));
return addHeapObject(ret);
imports.wbg.__wbg_sethref_90b000c8b01f96b1 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).href = getStringFromWasm0(arg1, arg2);
}, arguments) };
imports.wbg.__wbg_get_9e3c11077651eda8 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
imports.wbg.__wbg_pathname_1ab7e82aaa4511ff = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_search_9f7ca8896c2d0804 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).search;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_hash_be2940ca236b5efc = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_headers_d135d2bb8cc60413 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_instanceof_HtmlFormElement_eb100a9bdacc9fe6 = function(arg0) {
imports.wbg.__wbg_newwithstrandinit_f581dff0d19a8b03 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_Response_4c3b1446206114d1 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Response;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_status_d6d47ad2837621eb = function(arg0) {
const ret = getObject(arg0).status;
return ret;
};
imports.wbg.__wbg_headers_24def508a7518df9 = function(arg0) {
const ret = getObject(arg0).headers;
return addHeapObject(ret);
};
imports.wbg.__wbg_json_34535d9848f043eb = function() { return handleError(function (arg0) {
const ret = getObject(arg0).json();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlFormElement_7d89e65c39841f5c = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLFormElement;
@ -877,45 +877,45 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_parentNode_e1c214fc3f362af0 = function(arg0) {
imports.wbg.__wbg_parentNode_92a7017b3a4fad43 = function(arg0) {
const ret = getObject(arg0).parentNode;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_parentElement_592cb54944d3d002 = function(arg0) {
imports.wbg.__wbg_parentElement_72e144c2e8d9e0b5 = function(arg0) {
const ret = getObject(arg0).parentElement;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_lastChild_b17b3c7498d25bd7 = function(arg0) {
imports.wbg.__wbg_lastChild_a62e3fbaab87f734 = function(arg0) {
const ret = getObject(arg0).lastChild;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_nextSibling_d029031876ed1b1b = function(arg0) {
imports.wbg.__wbg_nextSibling_bafccd3347d24543 = function(arg0) {
const ret = getObject(arg0).nextSibling;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_setnodeValue_321840a6762ab272 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_setnodeValue_630c6470d05b600e = function(arg0, arg1, arg2) {
getObject(arg0).nodeValue = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_textContent_d69d000f6081b514 = function(arg0, arg1) {
imports.wbg.__wbg_textContent_2f37235e13f8484b = function(arg0, arg1) {
const ret = getObject(arg1).textContent;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_appendChild_2e6a6c9d1f0d443d = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_appendChild_d30e6b83791d04c0 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).appendChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_insertBefore_bdaeec8969497673 = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_insertBefore_726c1640c419e940 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).insertBefore(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_removeChild_a63022ebbfa6ebf5 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_removeChild_942eb9c02243d84d = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).removeChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_ShadowRoot_f85f709c953844de = function(arg0) {
imports.wbg.__wbg_instanceof_ShadowRoot_0bd39e89ab117f86 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof ShadowRoot;
@ -925,94 +925,94 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_host_73c8e95bf9b31ccd = function(arg0) {
imports.wbg.__wbg_host_09eee5e3d9cf59a1 = function(arg0) {
const ret = getObject(arg0).host;
return addHeapObject(ret);
};
imports.wbg.__wbg_get_4a9aa5157afeb382 = function(arg0, arg1) {
imports.wbg.__wbg_get_f01601b5a68d10e3 = function(arg0, arg1) {
const ret = getObject(arg0)[arg1 >>> 0];
return addHeapObject(ret);
};
imports.wbg.__wbg_length_cace2e0b3ddc0502 = function(arg0) {
imports.wbg.__wbg_length_1009b1af0c481d7b = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbg_new_08236689f0afb357 = function() {
imports.wbg.__wbg_new_ffc6d4d085022169 = function() {
const ret = new Array();
return addHeapObject(ret);
};
imports.wbg.__wbg_newnoargs_ccdcae30fd002262 = function(arg0, arg1) {
imports.wbg.__wbg_newnoargs_c62ea9419c21fbac = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_new_1b94180eeb48f2a2 = function() {
imports.wbg.__wbg_new_bfd4534b584a9593 = function() {
const ret = new Map();
return addHeapObject(ret);
};
imports.wbg.__wbg_next_15da6a3df9290720 = function(arg0) {
imports.wbg.__wbg_next_9b877f231f476d01 = function(arg0) {
const ret = getObject(arg0).next;
return addHeapObject(ret);
};
imports.wbg.__wbg_next_1989a20442400aaa = function() { return handleError(function (arg0) {
imports.wbg.__wbg_next_6529ee0cca8d57ed = function() { return handleError(function (arg0) {
const ret = getObject(arg0).next();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_done_bc26bf4ada718266 = function(arg0) {
imports.wbg.__wbg_done_5fe336b092d60cf2 = function(arg0) {
const ret = getObject(arg0).done;
return ret;
};
imports.wbg.__wbg_value_0570714ff7d75f35 = function(arg0) {
imports.wbg.__wbg_value_0c248a78fdc8e19f = function(arg0) {
const ret = getObject(arg0).value;
return addHeapObject(ret);
};
imports.wbg.__wbg_iterator_7ee1a391d310f8e4 = function() {
imports.wbg.__wbg_iterator_db7ca081358d4fb2 = function() {
const ret = Symbol.iterator;
return addHeapObject(ret);
};
imports.wbg.__wbg_get_2aff440840bb6202 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_get_7b48513de5dc5ea4 = function() { return handleError(function (arg0, arg1) {
const ret = Reflect.get(getObject(arg0), getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_call_669127b9d730c650 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_call_90c26b09837aba1c = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).call(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_new_c728d68b8b34487e = function() {
imports.wbg.__wbg_new_9fb8d994e1c0aaac = function() {
const ret = new Object();
return addHeapObject(ret);
};
imports.wbg.__wbg_self_3fad056edded10bd = function() { return handleError(function () {
imports.wbg.__wbg_self_f0e34d89f33b99fd = function() { return handleError(function () {
const ret = self.self;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_window_a4f46c98a61d4089 = function() { return handleError(function () {
imports.wbg.__wbg_window_d3b084224f4774d7 = function() { return handleError(function () {
const ret = window.window;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_globalThis_17eff828815f7d84 = function() { return handleError(function () {
imports.wbg.__wbg_globalThis_9caa27ff917c6860 = function() { return handleError(function () {
const ret = globalThis.globalThis;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_global_46f939f6541643c5 = function() { return handleError(function () {
imports.wbg.__wbg_global_35dfdd59a4da3e74 = function() { return handleError(function () {
const ret = global.global;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_set_0ac78a2bc07da03c = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_f2740edb12e318cd = function(arg0, arg1, arg2) {
getObject(arg0)[arg1 >>> 0] = takeObject(arg2);
};
imports.wbg.__wbg_from_ba72c50feaf1d8c0 = function(arg0) {
imports.wbg.__wbg_from_71add2e723d1f1b2 = function(arg0) {
const ret = Array.from(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_isArray_38525be7442aa21e = function(arg0) {
imports.wbg.__wbg_isArray_74fb723e24f76012 = function(arg0) {
const ret = Array.isArray(getObject(arg0));
return ret;
};
imports.wbg.__wbg_push_fd3233d09cf81821 = function(arg0, arg1) {
imports.wbg.__wbg_push_901f3914205d44de = function(arg0, arg1) {
const ret = getObject(arg0).push(getObject(arg1));
return ret;
};
imports.wbg.__wbg_instanceof_ArrayBuffer_c7cc317e5c29cc0d = function(arg0) {
imports.wbg.__wbg_instanceof_ArrayBuffer_e7d53d51371448e2 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof ArrayBuffer;
@ -1022,7 +1022,7 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_Error_9f5881c3c4149389 = function(arg0) {
imports.wbg.__wbg_instanceof_Error_31ca8d97f188bfbc = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Error;
@ -1032,78 +1032,78 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_message_35f9b952e1b922e2 = function(arg0) {
imports.wbg.__wbg_message_55b9ea8030688597 = function(arg0) {
const ret = getObject(arg0).message;
return addHeapObject(ret);
};
imports.wbg.__wbg_name_e1152a59269f79e5 = function(arg0) {
imports.wbg.__wbg_name_e5eede664187fed6 = function(arg0) {
const ret = getObject(arg0).name;
return addHeapObject(ret);
};
imports.wbg.__wbg_toString_d0cefe4046ecb265 = function(arg0) {
imports.wbg.__wbg_toString_a44236e90224e279 = function(arg0) {
const ret = getObject(arg0).toString();
return addHeapObject(ret);
};
imports.wbg.__wbg_set_3355b9f2d3092e3b = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_d257c6f2da008627 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_isSafeInteger_c38b0a16d0c7cef7 = function(arg0) {
imports.wbg.__wbg_isSafeInteger_f93fde0dca9820f8 = function(arg0) {
const ret = Number.isSafeInteger(getObject(arg0));
return ret;
};
imports.wbg.__wbg_new0_ad75dd38f92424e2 = function() {
imports.wbg.__wbg_new0_622c21a64f3d83ea = function() {
const ret = new Date();
return addHeapObject(ret);
};
imports.wbg.__wbg_now_4579335d3581594c = function() {
imports.wbg.__wbg_now_096aa89623f72d50 = function() {
const ret = Date.now();
return ret;
};
imports.wbg.__wbg_toISOString_a6b87a1eaae248de = function(arg0) {
imports.wbg.__wbg_toISOString_0f6525214134a4b6 = function(arg0) {
const ret = getObject(arg0).toISOString();
return addHeapObject(ret);
};
imports.wbg.__wbg_entries_6d727b73ee02b7ce = function(arg0) {
imports.wbg.__wbg_entries_9e2e2aa45aa5094a = function(arg0) {
const ret = Object.entries(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_is_c74aa9bb973d6109 = function(arg0, arg1) {
imports.wbg.__wbg_is_ff7acd231c75c0e4 = function(arg0, arg1) {
const ret = Object.is(getObject(arg0), getObject(arg1));
return ret;
};
imports.wbg.__wbg_resolve_a3252b2860f0a09e = function(arg0) {
imports.wbg.__wbg_resolve_6e1c6553a82f85b7 = function(arg0) {
const ret = Promise.resolve(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_then_89e1c559530b85cf = function(arg0, arg1) {
imports.wbg.__wbg_then_3ab08cd4fbb91ae9 = function(arg0, arg1) {
const ret = getObject(arg0).then(getObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_then_1bbc9edafd859b06 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_then_8371cc12cfedc5a2 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_buffer_344d9b41efe96da7 = function(arg0) {
imports.wbg.__wbg_buffer_a448f833075b71ba = function(arg0) {
const ret = getObject(arg0).buffer;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithbyteoffsetandlength_2dc04d99088b15e3 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_newwithbyteoffsetandlength_d0482f893617af71 = function(arg0, arg1, arg2) {
const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
return addHeapObject(ret);
};
imports.wbg.__wbg_new_d8a000788389a31e = function(arg0) {
imports.wbg.__wbg_new_8f67e318f15d7254 = function(arg0) {
const ret = new Uint8Array(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_set_dcfd613a3420f908 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_2357bf09366ee480 = function(arg0, arg1, arg2) {
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
};
imports.wbg.__wbg_length_a5587d6cd79ab197 = function(arg0) {
imports.wbg.__wbg_length_1d25fa9e4ac21ce7 = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbg_instanceof_Uint8Array_19e6f142a5e7e1e1 = function(arg0) {
imports.wbg.__wbg_instanceof_Uint8Array_bced6f43aed8c1aa = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Uint8Array;
@ -1113,11 +1113,11 @@ function __wbg_get_imports() {
const ret = result;
return ret;
};
imports.wbg.__wbg_set_40f7786a25a9cc7e = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_set_759f75cd92b612d2 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
return ret;
}, arguments) };
imports.wbg.__wbg_stringify_4039297315a25b00 = function() { return handleError(function (arg0) {
imports.wbg.__wbg_stringify_e1b19966d964d242 = function() { return handleError(function (arg0) {
const ret = JSON.stringify(getObject(arg0));
return addHeapObject(ret);
}, arguments) };
@ -1141,20 +1141,20 @@ function __wbg_get_imports() {
const ret = wasm.memory;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper1393 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 770, __wbg_adapter_48);
imports.wbg.__wbindgen_closure_wrapper1150 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 572, __wbg_adapter_48);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper3682 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1704, __wbg_adapter_51);
imports.wbg.__wbindgen_closure_wrapper3558 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1660, __wbg_adapter_51);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper3781 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1746, __wbg_adapter_54);
imports.wbg.__wbindgen_closure_wrapper3751 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1707, __wbg_adapter_54);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper3863 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1777, __wbg_adapter_57);
imports.wbg.__wbindgen_closure_wrapper3835 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1738, __wbg_adapter_57);
return addHeapObject(ret);
};

View file

@ -8,7 +8,7 @@ use wasm_bindgen::UnwrapThrowExt;
use wasm_bindgen_futures::JsFuture;
use yew::prelude::*;
use super::reset::{EventBusMsg, ModalProps};
use super::reset::{EventBusMsg, PasskeyClass, PasskeyModalProps};
use kanidmd_web_ui_shared::{do_request, utils, RequestMethod};
pub struct PasskeyModalApp {
@ -87,7 +87,9 @@ impl PasskeyModalApp {
emsg: "Invalid Passkey reg state response".to_string(),
kopid,
},
CURegState::Passkey(challenge) => Msg::ChallengeReady(challenge),
CURegState::AttestedPasskey(challenge) | CURegState::Passkey(challenge) => {
Msg::ChallengeReady(challenge)
}
CURegState::None => Msg::Success,
})
} else {
@ -99,7 +101,7 @@ impl PasskeyModalApp {
impl Component for PasskeyModalApp {
type Message = Msg;
type Properties = ModalProps;
type Properties = PasskeyModalProps;
fn create(_ctx: &Context<Self>) -> Self {
console::debug!("passkey modal create");
@ -128,14 +130,13 @@ impl Component for PasskeyModalApp {
// Init a fetch to get the challenge.
let token_c = ctx.props().token.clone();
let req = match &ctx.props().class {
PasskeyClass::Any => CURequest::PasskeyFinish(label, rpkc),
PasskeyClass::Attested => CURequest::AttestedPasskeyFinish(label, rpkc),
};
ctx.link().send_future(async {
match Self::submit_passkey_update(
token_c,
CURequest::PasskeyFinish(label, rpkc),
cb,
)
.await
{
match Self::submit_passkey_update(token_c, req, cb).await {
Ok(v) => v,
Err(v) => v.into(),
}
@ -152,8 +153,13 @@ impl Component for PasskeyModalApp {
// Init a fetch to get the challenge.
let token_c = ctx.props().token.clone();
let req = match &ctx.props().class {
PasskeyClass::Any => CURequest::PasskeyInit,
PasskeyClass::Attested => CURequest::AttestedPasskeyInit,
};
ctx.link().send_future(async {
match Self::submit_passkey_update(token_c, CURequest::PasskeyInit, cb).await {
match Self::submit_passkey_update(token_c, req, cb).await {
Ok(v) => v,
Err(v) => v.into(),
}
@ -175,6 +181,9 @@ impl Component for PasskeyModalApp {
.navigator()
.credentials()
.create_with_options(&c_options)
.map_err(|e| {
console::error!(format!("error -> {:?}", e).as_str());
})
.expect_throw("Unable to create promise");
let fut = JsFuture::from(promise);
@ -248,16 +257,39 @@ impl Component for PasskeyModalApp {
}
}
State::ChallengeReady(_challenge) => {
let allowed_devices = ctx.props().allowed_devices.clone();
// This works around a bug in safari :(
html! {
<button id="passkey-generate" type="button" class="btn btn-primary"
onclick={
ctx.link()
.callback(move |_| {
Msg::CredentialCreate
})
<>
{
if let Some(allowed_devices) = allowed_devices {
html! {
<>
<p>{ "The following devices are allowed to register" }</p>
<ul>
{
for allowed_devices.iter().map(|dev|
html!{
<li> { dev } </li>
}
)
}
</ul>
</>
}
} else {
html!{ <></> }
}
}
>{ "Begin Passkey Enrollment" }</button>
<button id="passkey-generate" type="button" class="btn btn-primary"
onclick={
ctx.link()
.callback(move |_| {
Msg::CredentialCreate
})
}
>{ "Begin Passkey Enrollment" }</button>
</>
}
}
State::CredentialReady(_) => {

View file

@ -6,7 +6,7 @@ use uuid::Uuid;
use wasm_bindgen::UnwrapThrowExt;
use yew::prelude::*;
use super::reset::{EventBusMsg, PasskeyRemoveModalProps};
use super::reset::{EventBusMsg, PasskeyClass, PasskeyRemoveModalProps};
use kanidmd_web_ui_shared::{do_request, error::FetchError, utils, RequestMethod};
pub struct PasskeyRemoveModalApp {
@ -91,6 +91,7 @@ impl PasskeyRemoveModalApp {
| CURegState::TotpTryAgain
| CURegState::TotpInvalidSha1
| CURegState::Passkey(_)
| CURegState::AttestedPasskey(_)
| CURegState::BackupCodes(_) => Msg::Error {
emsg: "Invalid Passkey reg state response".to_string(),
kopid,
@ -140,12 +141,16 @@ impl Component for PasskeyRemoveModalApp {
// Do the call back.
let token_c = ctx.props().token.clone();
let class = &ctx.props().class;
let uuid = self.uuid;
let request = match class {
PasskeyClass::Any => CURequest::PasskeyRemove(uuid),
PasskeyClass::Attested => CURequest::AttestedPasskeyRemove(uuid),
};
ctx.link().send_future(async move {
match Self::submit_passkey_update(token_c, CURequest::PasskeyRemove(uuid), cb)
.await
{
match Self::submit_passkey_update(token_c, request, cb).await {
Ok(v) => v,
Err(v) => v.into(),
}

View file

@ -44,9 +44,24 @@ pub struct TotpRemoveProps {
pub cb: Callback<EventBusMsg>,
}
#[derive(PartialEq)]
pub enum PasskeyClass {
Any,
Attested,
}
#[derive(PartialEq, Properties)]
pub struct PasskeyModalProps {
pub token: CUSessionToken,
pub class: PasskeyClass,
pub allowed_devices: Option<Vec<String>>,
pub cb: Callback<EventBusMsg>,
}
#[derive(PartialEq, Properties)]
pub struct PasskeyRemoveModalProps {
pub token: CUSessionToken,
pub class: PasskeyClass,
pub tag: String,
pub uuid: Uuid,
pub cb: Callback<EventBusMsg>,
@ -356,6 +371,9 @@ impl CredentialResetApp {
primary_state,
passkeys,
passkeys_state,
attested_passkeys,
attested_passkeys_state,
attested_passkeys_allowed_devices,
} = status;
let displayname = displayname.clone();
@ -382,6 +400,12 @@ impl CredentialResetApp {
let pw_html = self.view_primary(token, primary, *primary_state);
let passkey_html = self.view_passkeys(token, passkeys, *passkeys_state);
let attested_passkey_html = self.view_attested_passkeys(
token,
attested_passkeys,
*attested_passkeys_state,
attested_passkeys_allowed_devices.as_slice(),
);
let warnings_html = if warnings.is_empty() {
html! { <></> }
@ -403,6 +427,22 @@ impl CredentialResetApp {
<p>{ "Passkeys are required for your account." }</p>
</div>
},
CURegWarning::AttestedPasskeyRequired => html! {
<div class="alert alert-warning" role="alert">
<p>{ "Attested Passkeys are required for your account." }</p>
</div>
},
CURegWarning::AttestedResidentKeyRequired => html! {
<div class="alert alert-warning" role="alert">
<p>{ "Attested Resident Keys are required for your account." }</p>
</div>
},
CURegWarning::WebauthnAttestationUnsatisfiable => html! {
<div class="alert alert-danger" role="alert">
<p>{ "A webauthn attestation policy conflict has occurred and you will not be able to save your credentials" }</p>
<p>{ "Contact support IMMEDIATELY." }</p>
</div>
},
CURegWarning::Unsatisfiable => html! {
<div class="alert alert-danger" role="alert">
<p>{ "An account policy conflict has occurred and you will not be able to save your credentials" }</p>
@ -434,12 +474,10 @@ impl CredentialResetApp {
{ warnings_html }
<hr class="my-4" />
{ attested_passkey_html }
{ passkey_html }
<hr class="my-4" />
{ pw_html }
<hr class="my-4" />
@ -589,6 +627,14 @@ impl CredentialResetApp {
}
}
}
} else if matches!(primary_state, CUCredState::DeleteOnly) {
html! {
<p>
<button type="button" class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#staticDeletePrimaryCred">
{ "Delete this Legacy Credential" }
</button>
</p>
}
} else {
html! {<></>}
};
@ -602,6 +648,14 @@ impl CredentialResetApp {
</>
}
}
CUCredState::DeleteOnly => {
html! {
<>
<p>{ "Legacy password paired with other authentication factors." }</p>
<p>{ "Account policy prevents you modifying this credential, but you may remove it." }</p>
</>
}
}
CUCredState::AccessDeny => {
html! { <><p> { "You do not have access to modify the Password or TOTP tokens of this account" }</p></> }
}
@ -612,6 +666,8 @@ impl CredentialResetApp {
html! {
<>
<hr class="my-4" />
<h4>{"Password / TOTP"}</h4>
{ pw_warn }
{ pw_html_inner }
@ -629,48 +685,91 @@ impl CredentialResetApp {
) -> Html {
let cb = self.cb.clone();
let passkey_html_inner = match passkeys_state {
CUCredState::Modifiable => {
if passkeys.is_empty() {
html! {
<>
<p>{ "Strong cryptographic authenticators with self contained multi-factor authentication." }</p>
<p>{ "No Passkeys Registered" }</p>
<PasskeyModalApp token={ token.clone() } cb={ cb } />
</>
match passkeys_state {
CUCredState::DeleteOnly | CUCredState::Modifiable => {
html! {
<>
<hr class="my-4" />
<h4>{"Passkeys"}</h4>
<p>{ "Strong cryptographic authenticators with self contained multi-factor authentication." }</p>
{ if passkeys.is_empty() {
html! { <p>{ "No Passkeys Registered" }</p> }
} else {
html! { <></> }
} }
{ for passkeys.iter()
.map(|detail|
PasskeyRemoveModalApp::render_button(&detail.tag, detail.uuid)
)
}
} else {
html! {
<>
<p>{ "Strong cryptographic authenticators with self contained multi-factor authentication." }</p>
{ for passkeys.iter()
.map(|detail|
PasskeyRemoveModalApp::render_button(&detail.tag, detail.uuid)
)
}
{ for passkeys.iter()
.map(|detail|
html! { <PasskeyRemoveModalApp token={ token.clone() } tag={ detail.tag.clone() } uuid={ detail.uuid } cb={ cb.clone() } /> }
)
}
<PasskeyModalApp token={ token.clone() } cb={ cb.clone() } />
</>
{ for passkeys.iter()
.map(|detail|
html! { <PasskeyRemoveModalApp token={ token.clone() } tag={ detail.tag.clone() } uuid={ detail.uuid } cb={ cb.clone() } class={ PasskeyClass::Any } /> }
)
}
{ if passkeys_state == CUCredState::Modifiable {
html! { <PasskeyModalApp token={ token.clone() } cb={ cb.clone() } class={ PasskeyClass::Any } /> }
} else {
html! { <></> }
}}
</>
}
}
CUCredState::AccessDeny => {
html! { <><p> { "You do not have access to modify the Passkeys of this account" }</p></> }
html! { <></> }
}
CUCredState::PolicyDeny => {
html! { <><p> { "Account policy prevents you modifying the Passkeys of this account" }</p></> }
html! { <></> }
}
};
}
}
html! {
<>
<h4>{"Passkeys"}</h4>
{ passkey_html_inner }
</>
fn view_attested_passkeys(
&self,
token: &CUSessionToken,
attested_passkeys: &Vec<PasskeyDetail>,
attested_passkeys_state: CUCredState,
attested_passkeys_allowed_devices: &[String],
) -> Html {
let cb = self.cb.clone();
match attested_passkeys_state {
CUCredState::Modifiable | CUCredState::DeleteOnly => {
html! {
<>
<hr class="my-4" />
<h4>{"Attested Passkeys"}</h4>
{ if attested_passkeys.is_empty() { html! { <p> { "No Passkeys Registered" } </p> } } else { html! {<></>} } }
{ for attested_passkeys.iter()
.map(|detail|
PasskeyRemoveModalApp::render_button(&detail.tag, detail.uuid)
)
}
{ for attested_passkeys.iter()
.map(|detail|
html! { <PasskeyRemoveModalApp token={ token.clone() } tag={ detail.tag.clone() } uuid={ detail.uuid } cb={ cb.clone() } class={ PasskeyClass::Attested } /> }
)
}
{
if attested_passkeys_state == CUCredState::Modifiable {
html! { <PasskeyModalApp token={ token.clone() } cb={ cb } class={ PasskeyClass::Attested } allowed_devices={ Some(attested_passkeys_allowed_devices.to_vec()) } /> }
} else {
html! { <></> }
}
}
</>
}
}
CUCredState::AccessDeny | CUCredState::PolicyDeny => {
// Don't display anything.
html! { <></> }
}
}
}

View file

@ -87,7 +87,9 @@ impl TotpModalApp {
});
Ok(match status.mfaregstate {
CURegState::Passkey(_) | CURegState::BackupCodes(_) => Msg::Error {
CURegState::Passkey(_)
| CURegState::AttestedPasskey(_)
| CURegState::BackupCodes(_) => Msg::Error {
emsg: "Invalid TOTP mfa reg state response".to_string(),
kopid,
},

View file

@ -53,6 +53,8 @@ RUN \
--target-dir="/usr/src/kanidm/target/" \
--features="${KANIDM_FEATURES}" \
--release && \
cargo install --force fido-mds-tool \
--target-dir="/usr/src/kanidm/target/" && \
sccache -s
# == Construct the tools container
@ -69,11 +71,13 @@ RUN \
COPY --from=builder /usr/src/kanidm/target/release/kanidm /sbin/
COPY --from=builder /usr/src/kanidm/target/release/kanidm-ipa-sync /sbin/
COPY --from=builder /usr/src/kanidm/target/release/kanidm-ldap-sync /sbin/
COPY --from=builder /usr/src/kanidm/target/release/fido-mds-tool /sbin/
RUN chmod +x /sbin/kanidm
RUN chmod +x /sbin/kanidm-ipa-sync
RUN chmod +x /sbin/kanidm-ldap-sync
RUN chmod +x /sbin/fido-mds-tool
RUN mkdir /etc/kanidm && \
touch /etc/kanidm/config
CMD [ "/sbin/kanidm", "-h" ]
CMD [ "/sbin/kanidm", "-h" ]

View file

@ -8,6 +8,7 @@ impl GroupAccountPolicyOpt {
| GroupAccountPolicyOpt::AuthSessionExpiry { copt, .. }
| GroupAccountPolicyOpt::CredentialTypeMinimum { copt, .. }
| GroupAccountPolicyOpt::PasswordMinimumLength { copt, .. }
| GroupAccountPolicyOpt::WebauthnAttestationCaList { copt, .. }
| GroupAccountPolicyOpt::PrivilegedSessionExpiry { copt, .. } => copt.debug,
}
}
@ -36,12 +37,12 @@ impl GroupAccountPolicyOpt {
GroupAccountPolicyOpt::CredentialTypeMinimum { name, value, copt } => {
let client = copt.to_client(OpType::Write).await;
if let Err(e) = client
.group_account_policy_credential_type_minimum_set(name, value)
.group_account_policy_credential_type_minimum_set(name, value.as_str())
.await
{
handle_client_error(e, copt.output_mode);
} else {
println!("Updated credential type minimum expiry.");
println!("Updated credential type minimum.");
}
}
GroupAccountPolicyOpt::PasswordMinimumLength { name, length, copt } => {
@ -63,7 +64,22 @@ impl GroupAccountPolicyOpt {
{
handle_client_error(e, copt.output_mode);
} else {
println!("Updated authsession expiry.");
println!("Updated privilege session expiry.");
}
}
GroupAccountPolicyOpt::WebauthnAttestationCaList {
name,
attestation_ca_list_json,
copt,
} => {
let client = copt.to_client(OpType::Write).await;
if let Err(e) = client
.group_account_policy_webauthn_attestation_set(name, attestation_ca_list_json)
.await
{
handle_client_error(e, copt.output_mode);
} else {
println!("Updated webauthn attesation CA list.");
}
}
}

View file

@ -616,6 +616,8 @@ enum CUAction {
Remove,
Passkey,
PasskeyRemove,
AttestedPasskey,
AttestedPasskeyRemove,
End,
Commit,
}
@ -638,6 +640,9 @@ remove (rm) - Remove only the password based credential
-- Passkeys
passkey (pk) - Add a new Passkey
passkey remove (passkey rm, pkrm) - Remove a Passkey
-- Attested Passkeys
attested-passkey (apk) - Add a new Attested Passkey
attested-passkey-remove (attested-passkey rm, apkrm) - Remove an Attested Passkey
"#
)
}
@ -660,6 +665,10 @@ impl FromStr for CUAction {
"remove" | "rm" => Ok(CUAction::Remove),
"passkey" | "pk" => Ok(CUAction::Passkey),
"passkey remove" | "passkey rm" | "pkrm" => Ok(CUAction::PasskeyRemove),
"attested-passkey" | "apk" => Ok(CUAction::AttestedPasskey),
"attested-passkey remove" | "attested-passkey rm" | "apkrm" => {
Ok(CUAction::AttestedPasskeyRemove)
}
_ => Err(()),
}
}
@ -833,23 +842,66 @@ async fn totp_enroll_prompt(session_token: &CUSessionToken, client: &KanidmClien
// Done!
}
async fn passkey_enroll_prompt(session_token: &CUSessionToken, client: &KanidmClient) {
let pk_reg = match client
.idm_account_credential_update_passkey_init(session_token)
.await
{
Ok(CUStatus {
mfaregstate: CURegState::Passkey(pk_reg),
..
}) => pk_reg,
Ok(status) => {
debug!(?status);
eprintln!("An error occurred -> InvalidState");
return;
#[derive(Clone, Copy)]
enum PasskeyClass {
Any,
Attested,
}
impl fmt::Display for PasskeyClass {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PasskeyClass::Any => write!(f, "Passkey"),
PasskeyClass::Attested => write!(f, "Attested Passkey"),
}
Err(e) => {
eprintln!("An error occurred -> {:?}", e);
return;
}
}
async fn passkey_enroll_prompt(
session_token: &CUSessionToken,
client: &KanidmClient,
pk_class: PasskeyClass,
) {
let pk_reg = match pk_class {
PasskeyClass::Any => {
match client
.idm_account_credential_update_passkey_init(session_token)
.await
{
Ok(CUStatus {
mfaregstate: CURegState::Passkey(pk_reg),
..
}) => pk_reg,
Ok(status) => {
debug!(?status);
eprintln!("An error occurred -> InvalidState");
return;
}
Err(e) => {
eprintln!("An error occurred -> {:?}", e);
return;
}
}
}
PasskeyClass::Attested => {
match client
.idm_account_credential_update_attested_passkey_init(session_token)
.await
{
Ok(CUStatus {
mfaregstate: CURegState::AttestedPasskey(pk_reg),
..
}) => pk_reg,
Ok(status) => {
debug!(?status);
eprintln!("An error occurred -> InvalidState");
return;
}
Err(e) => {
eprintln!("An error occurred -> {:?}", e);
return;
}
}
}
};
@ -873,15 +925,108 @@ async fn passkey_enroll_prompt(session_token: &CUSessionToken, client: &KanidmCl
.interact_text()
.expect("Failed to interact with interactive session");
match pk_class {
PasskeyClass::Any => {
match client
.idm_account_credential_update_passkey_finish(session_token, label, rego)
.await
{
Ok(_) => println!("success"),
Err(e) => {
eprintln!("An error occurred -> {:?}", e);
}
}
}
PasskeyClass::Attested => {
match client
.idm_account_credential_update_attested_passkey_finish(session_token, label, rego)
.await
{
Ok(_) => println!("success"),
Err(e) => {
eprintln!("An error occurred -> {:?}", e);
}
}
}
}
}
async fn passkey_remove_prompt(
session_token: &CUSessionToken,
client: &KanidmClient,
pk_class: PasskeyClass,
) {
// TODO: make this a scrollable selector with a "cancel" option as the default
match client
.idm_account_credential_update_passkey_finish(session_token, label, rego)
.idm_account_credential_update_status(session_token)
.await
{
Ok(_) => println!("success"),
Ok(status) => match pk_class {
PasskeyClass::Any => {
if status.passkeys.is_empty() {
println!("No passkeys are configured for this user");
return;
}
println!("Current passkeys:");
for pk in status.passkeys {
println!(" {} ({})", pk.tag, pk.uuid);
}
}
PasskeyClass::Attested => {
if status.attested_passkeys.is_empty() {
println!("No attested passkeys are configured for this user");
return;
}
println!("Current attested passkeys:");
for pk in status.attested_passkeys {
println!(" {} ({})", pk.tag, pk.uuid);
}
}
},
Err(e) => {
eprintln!("An error occurred -> {:?}", e);
eprintln!(
"An error occurred retrieving existing credentials -> {:?}",
e
);
}
};
}
let uuid_s: String = Input::new()
.with_prompt("\nEnter the UUID of the Passkey to remove (blank to stop) # ")
.validate_with(|input: &String| -> Result<(), &str> {
if input.is_empty() || Uuid::parse_str(input).is_ok() {
Ok(())
} else {
Err("This is not a valid UUID")
}
})
.allow_empty(true)
.interact_text()
.expect("Failed to interact with interactive session");
// Remember, if it's NOT a valid uuid, it must have been empty as a termination.
if let Ok(uuid) = Uuid::parse_str(&uuid_s) {
let result = match pk_class {
PasskeyClass::Any => {
client
.idm_account_credential_update_passkey_remove(session_token, uuid)
.await
}
PasskeyClass::Attested => {
client
.idm_account_credential_update_attested_passkey_remove(session_token, uuid)
.await
}
};
if let Err(e) = result {
eprintln!("An error occurred -> {:?}", e);
} else {
println!("success");
}
} else {
println!("{}s were NOT changed", pk_class);
}
}
fn display_status(status: CUStatus) {
@ -896,6 +1041,9 @@ fn display_status(status: CUStatus) {
primary_state,
passkeys,
passkeys_state,
attested_passkeys,
attested_passkeys_state,
attested_passkeys_allowed_devices,
} = status;
println!("spn: {}", spn);
@ -922,6 +1070,15 @@ fn display_status(status: CUStatus) {
CURegWarning::PasskeyRequired => {
println!("Passkeys required");
}
CURegWarning::AttestedPasskeyRequired => {
println!("Attested Passkeys required");
}
CURegWarning::AttestedResidentKeyRequired => {
println!("Attested Resident Keys required");
}
CURegWarning::WebauthnAttestationUnsatisfiable => {
println!("Attestation is unsatisfiable. Contact your administrator.");
}
CURegWarning::Unsatisfiable => {
println!("Account policy is unsatisfiable. Contact your administrator.");
}
@ -938,6 +1095,13 @@ fn display_status(status: CUStatus) {
println!(" not set");
}
}
CUCredState::DeleteOnly => {
if let Some(cred_detail) = &primary {
print!("{}", cred_detail);
} else {
println!(" unable to modify - access denied");
}
}
CUCredState::AccessDeny => {
println!(" unable to modify - access denied");
}
@ -957,6 +1121,15 @@ fn display_status(status: CUStatus) {
}
}
}
CUCredState::DeleteOnly => {
if passkeys.is_empty() {
println!(" unable to modify - access denied");
} else {
for pk in passkeys {
println!(" {} ({})", pk.tag, pk.uuid);
}
}
}
CUCredState::AccessDeny => {
println!(" unable to modify - access denied");
}
@ -965,6 +1138,40 @@ fn display_status(status: CUStatus) {
}
}
println!("Attested Passkeys:");
match attested_passkeys_state {
CUCredState::Modifiable => {
if attested_passkeys.is_empty() {
println!(" not set");
} else {
for pk in attested_passkeys {
println!(" {} ({})", pk.tag, pk.uuid);
}
}
println!(" --");
println!(" The following devices models are allowed by account policy");
for dev in attested_passkeys_allowed_devices {
println!(" - {}", dev);
}
}
CUCredState::DeleteOnly => {
if attested_passkeys.is_empty() {
println!(" unable to modify - attestation policy not configured");
} else {
for pk in attested_passkeys {
println!(" {} ({})", pk.tag, pk.uuid);
}
}
}
CUCredState::AccessDeny => {
println!(" unable to modify - access denied");
}
CUCredState::PolicyDeny => {
println!(" unable to modify - attestation policy not configured");
}
}
// We may need to be able to display if there are dangling
// curegstates, but the cli ui statemachine can match the
// server so it may not be needed?
@ -1143,57 +1350,17 @@ async fn credential_update_exec(
println!("Primary credential was NOT removed");
}
}
CUAction::Passkey => passkey_enroll_prompt(&session_token, &client).await,
CUAction::Passkey => {
passkey_enroll_prompt(&session_token, &client, PasskeyClass::Any).await
}
CUAction::PasskeyRemove => {
// TODO: make this a scrollable selector with a "cancel" option as the default
match client
.idm_account_credential_update_status(&session_token)
.await
{
Ok(status) => {
if status.passkeys.is_empty() {
println!("No passkeys are configured for this user");
return;
}
println!("Current passkeys:");
for pk in status.passkeys {
println!(" {} ({})", pk.tag, pk.uuid);
}
}
Err(e) => {
eprintln!(
"An error occurred retrieving existing credentials -> {:?}",
e
);
}
}
let uuid_s: String = Input::new()
.with_prompt("\nEnter the UUID of the Passkey to remove (blank to stop) # ")
.validate_with(|input: &String| -> Result<(), &str> {
if input.is_empty() || Uuid::parse_str(input).is_ok() {
Ok(())
} else {
Err("This is not a valid UUID")
}
})
.allow_empty(true)
.interact_text()
.expect("Failed to interact with interactive session");
// Remember, if it's NOT a valid uuid, it must have been empty as a termination.
if let Ok(uuid) = Uuid::parse_str(&uuid_s) {
if let Err(e) = client
.idm_account_credential_update_passkey_remove(&session_token, uuid)
.await
{
eprintln!("An error occurred -> {:?}", e);
} else {
println!("success");
}
} else {
println!("Passkeys were NOT changed");
}
passkey_remove_prompt(&session_token, &client, PasskeyClass::Any).await
}
CUAction::AttestedPasskey => {
passkey_enroll_prompt(&session_token, &client, PasskeyClass::Attested).await
}
CUAction::AttestedPasskeyRemove => {
passkey_remove_prompt(&session_token, &client, PasskeyClass::Attested).await
}
CUAction::End => {
println!("Changes were NOT saved.");

View file

@ -1,4 +1,5 @@
use clap::{Args, Subcommand};
use clap::{Args, Subcommand, ValueEnum, builder::PossibleValue};
use std::fmt;
#[derive(Debug, Args)]
pub struct Named {
@ -35,7 +36,7 @@ impl std::str::FromStr for OutputMode {
impl OutputMode {
pub fn print_message<T>(self, input: T)
where
T: serde::Serialize + std::fmt::Debug + std::fmt::Display,
T: serde::Serialize + fmt::Debug + fmt::Display,
{
match self {
OutputMode::Json => {
@ -108,6 +109,40 @@ pub enum GroupPosix {
Set(GroupPosixOpt),
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum AccountPolicyCredentialType {
Any,
Mfa,
Passkey,
AttestedPasskey,
}
impl AccountPolicyCredentialType {
pub fn as_str(&self) -> &'static str {
match self {
Self::Any => "any",
Self::Mfa => "mfa",
Self::Passkey => "passkey",
Self::AttestedPasskey => "attested_passkey",
}
}
}
impl ValueEnum for AccountPolicyCredentialType {
fn value_variants<'a>() -> &'a [Self] {
&[Self::Any, Self::Mfa, Self::Passkey, Self::AttestedPasskey]
}
fn to_possible_value(&self) -> Option<PossibleValue> {
Some(match self {
Self::Any => PossibleValue::new("any"),
Self::Mfa => PossibleValue::new("mfa"),
Self::Passkey => PossibleValue::new("passkey"),
Self::AttestedPasskey => PossibleValue::new("attested_passkey"),
})
}
}
#[derive(Debug, Subcommand)]
pub enum GroupAccountPolicyOpt {
/// Enable account policy for this group
@ -125,11 +160,13 @@ pub enum GroupAccountPolicyOpt {
#[clap(flatten)]
copt: CommonOpt,
},
/// Set the maximum time for session expiry
/// Set the minimum credential class that members may authenticate with. Valid values
/// in order of weakest to strongest are: "any" "mfa" "passkey" "attested_passkey"
#[clap(name = "credential-type-minimum")]
CredentialTypeMinimum {
name: String,
value: String,
#[clap(value_enum)]
value: AccountPolicyCredentialType,
#[clap(flatten)]
copt: CommonOpt,
},
@ -141,7 +178,6 @@ pub enum GroupAccountPolicyOpt {
#[clap(flatten)]
copt: CommonOpt,
},
/// Configure and display the privilege session expiry
/// Set the maximum time for privilege session expiry
#[clap(name = "privilege-expiry")]
PrivilegedSessionExpiry {
@ -150,6 +186,17 @@ pub enum GroupAccountPolicyOpt {
#[clap(flatten)]
copt: CommonOpt,
},
/// The the webauthn attestation ca list that should be enforced
/// on members of this group. Prevents use of passkeys that are
/// in this list. To create this list, use `fido-mds-tool`
/// from <https://crates.io/crates/fido-mds-tool>
#[clap(name = "webauthn-attestation-ca-list")]
WebauthnAttestationCaList {
name: String,
attestation_ca_list_json: String,
#[clap(flatten)]
copt: CommonOpt,
},
}
#[derive(Debug, Subcommand)]

View file

@ -12,11 +12,34 @@ use std::path::PathBuf;
use clap::Parser;
use kanidm_client::{ClientError, KanidmClient, KanidmClientBuilder};
use kanidm_proto::constants::{DEFAULT_CLIENT_CONFIG_PATH, DEFAULT_CLIENT_CONFIG_PATH_HOME};
use tracing::{debug, error};
use tracing::error;
include!("opt/ssh_authorizedkeys.rs");
#[cfg(not(test))]
fn k_client_builder() -> Result<KanidmClientBuilder, ()> {
use kanidm_proto::constants::{DEFAULT_CLIENT_CONFIG_PATH, DEFAULT_CLIENT_CONFIG_PATH_HOME};
use tracing::debug;
let config_path: String = shellexpand::tilde(DEFAULT_CLIENT_CONFIG_PATH_HOME).into_owned();
debug!("Attempting to use config {}", DEFAULT_CLIENT_CONFIG_PATH);
KanidmClientBuilder::new()
.read_options_from_optional_config(DEFAULT_CLIENT_CONFIG_PATH)
.and_then(|cb| {
debug!("Attempting to use config {}", config_path);
cb.read_options_from_optional_config(config_path)
})
.map_err(|e| {
error!("Failed to parse config (if present) -- {:?}", e);
})
}
#[cfg(test)]
fn k_client_builder() -> Result<KanidmClientBuilder, ()> {
Ok(KanidmClientBuilder::new())
}
pub(crate) fn build_configured_client(opt: &SshAuthorizedOpt) -> Result<KanidmClient, ()> {
if opt.debug {
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
@ -26,17 +49,7 @@ pub(crate) fn build_configured_client(opt: &SshAuthorizedOpt) -> Result<KanidmCl
#[cfg(test)]
sketching::test_init();
let config_path: String = shellexpand::tilde(DEFAULT_CLIENT_CONFIG_PATH_HOME).into_owned();
debug!("Attempting to use config {}", DEFAULT_CLIENT_CONFIG_PATH);
let client_builder = KanidmClientBuilder::new()
.read_options_from_optional_config(DEFAULT_CLIENT_CONFIG_PATH)
.and_then(|cb| {
debug!("Attempting to use config {}", config_path);
cb.read_options_from_optional_config(config_path)
})
.map_err(|e| {
error!("Failed to parse config (if present) -- {:?}", e);
})?;
let client_builder = k_client_builder()?;
let client_builder = match &opt.addr {
Some(a) => client_builder.address(a.to_string()),