diff --git a/src/internet_identity/internet_identity.did b/src/internet_identity/internet_identity.did index 500ef4d6e8..bdaf682540 100644 --- a/src/internet_identity/internet_identity.did +++ b/src/internet_identity/internet_identity.did @@ -257,6 +257,8 @@ type InternetIdentityInit = record { register_rate_limit : opt RateLimitConfig; // Configuration of the captcha in the registration flow. captcha_config: opt CaptchaConfig; + // Configuration for Related Origins Requests + related_origins: opt vec text; }; type ChallengeKey = text; diff --git a/src/internet_identity/src/assets.rs b/src/internet_identity/src/assets.rs index 2de37e3bf6..087212ff54 100644 --- a/src/internet_identity/src/assets.rs +++ b/src/internet_identity/src/assets.rs @@ -6,14 +6,15 @@ use crate::state; use asset_util::{collect_assets, Asset, CertifiedAssets, ContentEncoding, ContentType}; use base64::engine::general_purpose::STANDARD as BASE64; use base64::Engine; -use ic_cdk::api; +use ic_cdk::{api, println}; use include_dir::{include_dir, Dir}; +use serde_json::json; use sha2::Digest; // used both in init and post_upgrade -pub fn init_assets() { +pub fn init_assets(maybe_related_origins: Option>) { state::assets_mut(|certified_assets| { - let assets = get_static_assets(); + let assets = get_static_assets(maybe_related_origins); // Extract integrity hashes for all inlined scripts, from all the HTML files. let integrity_hashes = assets @@ -47,7 +48,7 @@ fn fixup_html(html: &str) -> String { static ASSET_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/../../dist"); // Gets the static assets. All static assets are prepared only once (like injecting the canister ID). -pub fn get_static_assets() -> Vec { +pub fn get_static_assets(maybe_related_origins: Option>) -> Vec { let mut assets = collect_assets(&ASSET_DIR, Some(fixup_html)); // Required to make II available on the identity.internetcomputer.org domain. @@ -59,15 +60,26 @@ pub fn get_static_assets() -> Vec { content_type: ContentType::OCTETSTREAM, }); - // Required to share passkeys with the different domains. - // See https://web.dev/articles/webauthn-related-origin-requests#step_2_set_up_your_well-knownwebauthn_json_file_in_site-1 - // Maximum of 5 labels. If we want to support more, we'll need to set them in the configuration. - assets.push(Asset { - url_path: "/.well-known/webauthn".to_string(), - content: b"{\"origins\":[\"https://beta.identity.ic0.app\",\"https://beta.identity.internetcomputer.org\",\"https://identity.internetcomputer.org\",\"https://identity.ic0.app\",\"https://identity.icp0.io\"]}".to_vec(), - encoding: ContentEncoding::Identity, - content_type: ContentType::OCTETSTREAM, - }); + println!("in da get_static_assets"); + + // if let Some(related_origins) = maybe_related_origins { + // println!("related_origin: {}", related_origins[0]); + // // Serialize the content into JSON and convert it to a Vec + // let content = json!({ + // "origins": related_origins, + // }) + // .to_string() + // .into_bytes(); + // // Required to share passkeys with the different domains. + // // See https://web.dev/articles/webauthn-related-origin-requests#step_2_set_up_your_well-knownwebauthn_json_file_in_site-1 + // // Maximum of 5 labels. If we want to support more, we'll need to set them in the configuration. + // assets.push(Asset { + // url_path: "/.well-known/webauthn".to_string(), + // content, + // encoding: ContentEncoding::Identity, + // content_type: ContentType::OCTETSTREAM, + // }); + // } assets } diff --git a/src/internet_identity/src/main.rs b/src/internet_identity/src/main.rs index a709b4d34f..395f21e965 100644 --- a/src/internet_identity/src/main.rs +++ b/src/internet_identity/src/main.rs @@ -13,7 +13,7 @@ use authz_utils::{ use candid::Principal; use ic_canister_sig_creation::signature_map::LABEL_SIG; use ic_cdk::api::{caller, set_certified_data, trap}; -use ic_cdk::call; +use ic_cdk::{call, println}; use ic_cdk_macros::{init, post_upgrade, pre_upgrade, query, update}; use internet_identity_interface::archive::types::BufferedEntry; use internet_identity_interface::http_gateway::{HttpRequest, HttpResponse}; @@ -346,6 +346,7 @@ fn config() -> InternetIdentityInit { canister_creation_cycles_cost: Some(persistent_state.canister_creation_cycles_cost), register_rate_limit: Some(persistent_state.registration_rate_limit.clone()), captcha_config: Some(persistent_state.captcha_config.clone()), + related_origins: persistent_state.related_origins.clone(), }) } @@ -377,6 +378,7 @@ fn init(maybe_arg: Option) { #[post_upgrade] fn post_upgrade(maybe_arg: Option) { + println!("in da post_upgrade"); state::init_from_stable_memory(); // load the persistent state after initializing storage as it manages the respective stable cell state::load_persistent_state(); @@ -385,7 +387,11 @@ fn post_upgrade(maybe_arg: Option) { } fn initialize(maybe_arg: Option) { - init_assets(); + let state_related_origins = state::persistent_state(|storage| { + storage.related_origins.clone() + }); + let related_origins = maybe_arg.clone().map(|arg| arg.related_origins).unwrap_or(state_related_origins); + init_assets(related_origins); apply_install_arg(maybe_arg); update_root_hash(); } diff --git a/src/internet_identity/src/state.rs b/src/internet_identity/src/state.rs index c56aa197a2..b56c6e475c 100644 --- a/src/internet_identity/src/state.rs +++ b/src/internet_identity/src/state.rs @@ -103,6 +103,8 @@ pub struct PersistentState { pub active_authn_method_stats: ActivityStats, // Configuration of the captcha challenge during registration flow pub captcha_config: CaptchaConfig, + // Configuration for Related Origins Requests + pub related_origins: Option>, // Key into the event_data BTreeMap where the 24h tracking window starts. // This key is used to remove old entries from the 24h event aggregations. // If it is `none`, then the 24h window starts from the newest entry in the event_data @@ -121,6 +123,7 @@ impl Default for PersistentState { domain_active_anchor_stats: ActivityStats::new(time), active_authn_method_stats: ActivityStats::new(time), captcha_config: DEFAULT_CAPTCHA_CONFIG, + related_origins: None, event_stats_24h_start: None, } } diff --git a/src/internet_identity/src/storage/storable_persistent_state.rs b/src/internet_identity/src/storage/storable_persistent_state.rs index c3f8d1fcd8..90675ad470 100644 --- a/src/internet_identity/src/storage/storable_persistent_state.rs +++ b/src/internet_identity/src/storage/storable_persistent_state.rs @@ -32,6 +32,7 @@ pub struct StorablePersistentState { // opt fields because of backwards compatibility event_stats_24h_start: Option, captcha_config: Option, + related_origins: Option>, } impl Storable for StorablePersistentState { @@ -69,6 +70,7 @@ impl From for StorablePersistentState { max_inflight_captchas: 0, event_stats_24h_start: s.event_stats_24h_start, captcha_config: Some(s.captcha_config), + related_origins: s.related_origins, } } } @@ -84,6 +86,7 @@ impl From for PersistentState { active_authn_method_stats: s.active_authn_method_stats, captcha_config: s.captcha_config.unwrap_or(DEFAULT_CAPTCHA_CONFIG), event_stats_24h_start: s.event_stats_24h_start, + related_origins: s.related_origins, } } } @@ -127,6 +130,7 @@ mod tests { max_unsolved_captchas: 500, captcha_trigger: CaptchaTrigger::Static(StaticCaptchaTrigger::CaptchaEnabled), }), + related_origins: None, }; assert_eq!(StorablePersistentState::default(), expected_defaults); @@ -146,6 +150,7 @@ mod tests { captcha_trigger: CaptchaTrigger::Static(StaticCaptchaTrigger::CaptchaEnabled), }, event_stats_24h_start: None, + related_origins: None, }; assert_eq!(PersistentState::default(), expected_defaults); } diff --git a/src/internet_identity_interface/src/internet_identity/types.rs b/src/internet_identity_interface/src/internet_identity/types.rs index bfd97f3165..4d5fc66dee 100644 --- a/src/internet_identity_interface/src/internet_identity/types.rs +++ b/src/internet_identity_interface/src/internet_identity/types.rs @@ -195,6 +195,7 @@ pub struct InternetIdentityInit { pub canister_creation_cycles_cost: Option, pub register_rate_limit: Option, pub captcha_config: Option, + pub related_origins: Option>, } #[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)]