11use asset_util:: { collect_assets, Asset as AssetUtilAsset , ContentEncoding , ContentType } ;
22use base64:: engine:: general_purpose:: STANDARD as BASE64 ;
33use base64:: Engine ;
4- use candid:: { Encode , Principal } ;
4+ use candid:: { Encode , IDLValue } ;
55use flate2:: read:: GzDecoder ;
66use ic_asset_certification:: { Asset , AssetConfig , AssetEncoding , AssetRouter } ;
77use ic_cdk:: { init, post_upgrade} ;
88use ic_cdk_macros:: query;
99use ic_http_certification:: { HeaderField , HttpCertificationTree , HttpRequest , HttpResponse } ;
1010use include_dir:: { include_dir, Dir } ;
1111use internet_identity_interface:: internet_identity:: types:: {
12- DummyAuthConfig , InternetIdentityFrontendInit , InternetIdentityInit ,
12+ InternetIdentityFrontendArgs , InternetIdentityInit ,
1313} ;
14- use lazy_static:: lazy_static;
1514use serde_json:: json;
1615use sha2:: Digest ;
1716use std:: io:: Read ;
@@ -25,56 +24,19 @@ thread_local! {
2524static ASSETS_DIR : Dir < ' _ > = include_dir ! ( "$CARGO_MANIFEST_DIR/../../dist" ) ;
2625const IMMUTABLE_ASSET_CACHE_CONTROL : & str = "public, max-age=31536000, immutable" ;
2726const NO_CACHE_ASSET_CACHE_CONTROL : & str = "public, no-cache, no-store" ;
28- const MISSING_MANDATORY_INTERNET_IDENTITY_FRONTEND_INSTALL_ARGS_HTML_ERROR : & str =
29- "<!doctype html>\
30- <html>\
31- <head><title>Internet Identity Frontend Initialization Error</title></head>\
32- <body><h1>Internet Identity Frontend Initialization Error</h1>\
33- <p>
34- Please initialize this canister with the following required install args:
35- <ul>
36- <li>backend_canister_id</li>
37- <li>backend_origin</li>
38- </ul>
39- </p>\
40- </body></html>";
41-
42- // Default configuration for the frontend canister
43- lazy_static ! {
44- // TODO: Change this to the mainnet value `rdmx6-jaaaa-aaaaa-aaadq-cai` before deploying to mainnet.
45- static ref DEFAULT_INTERNET_IDENTITY_BACKEND_CANISTER_ID : Principal =
46- Principal :: from_text( "uxrrr-q7777-77774-qaaaq-cai" ) . unwrap( ) ;
47-
48- static ref DEFAULT_CONFIG : InternetIdentityFrontendInit = InternetIdentityFrontendInit {
49- backend_canister_id: Some ( * DEFAULT_INTERNET_IDENTITY_BACKEND_CANISTER_ID ) ,
50- backend_origin: Some ( "https://backend.id.ai" . to_string( ) ) ,
51- related_origins: Some ( vec![
52- "https://id.ai" . to_string( ) ,
53- "https://identity.internetcomputer.org" . to_string( ) ,
54- "https://identity.ic0.app" . to_string( ) ,
55- ] ) ,
56- openid_configs: None ,
57- dummy_auth: Some ( Some ( DummyAuthConfig {
58- prompt_for_index: true
59- } ) ) ,
60- fetch_root_key: None ,
61- analytics_config: None ,
62- } ;
63- }
6427
6528#[ init]
66- fn init ( init_arg : Option < InternetIdentityFrontendInit > ) {
67- let config = init_arg. unwrap_or_else ( || DEFAULT_CONFIG . clone ( ) ) ;
68- certify_all_assets ( config) ;
29+ fn init ( args : InternetIdentityFrontendArgs ) {
30+ certify_all_assets ( args) ;
6931}
7032
7133#[ post_upgrade]
72- fn post_upgrade ( ) {
73- init ( None ) ;
34+ fn post_upgrade ( args : InternetIdentityFrontendArgs ) {
35+ certify_all_assets ( args ) ;
7436}
7537
76- fn certify_all_assets ( init : InternetIdentityFrontendInit ) {
77- let static_assets = get_static_assets ( & init ) ;
38+ fn certify_all_assets ( args : InternetIdentityFrontendArgs ) {
39+ let static_assets = get_static_assets ( & args ) ;
7840
7941 // 2. Extract integrity hashes for inline scripts from HTML files
8042 let integrity_hashes = static_assets
@@ -137,7 +99,7 @@ fn certify_all_assets(init: InternetIdentityFrontendInit) {
13799 vec ! [ AssetEncoding :: Identity . default_config( ) ]
138100 } ;
139101
140- let headers = if path. starts_with ( "_app/immutable" ) {
102+ let headers = if path. starts_with ( "/ _app/immutable" ) {
141103 (
142104 "cache-control" . to_string ( ) ,
143105 IMMUTABLE_ASSET_CACHE_CONTROL . to_string ( ) ,
@@ -333,7 +295,7 @@ fn get_content_security_policy(integrity_hashes: Vec<String>) -> String {
333295}
334296
335297/// Gets the static assets with HTML fixup and well-known endpoints
336- fn get_static_assets ( config : & InternetIdentityFrontendInit ) -> Vec < AssetUtilAsset > {
298+ fn get_static_assets ( config : & InternetIdentityFrontendArgs ) -> Vec < AssetUtilAsset > {
337299 // Collect assets and fix up HTML files
338300 let mut assets: Vec < AssetUtilAsset > = collect_assets ( & ASSETS_DIR , None )
339301 . into_iter ( )
@@ -347,6 +309,18 @@ fn get_static_assets(config: &InternetIdentityFrontendInit) -> Vec<AssetUtilAsse
347309 } )
348310 . collect ( ) ;
349311
312+ // Serve the initialization argument of this canister as a Candid file
313+ assets. push ( AssetUtilAsset {
314+ url_path : "/.config" . to_string ( ) ,
315+ content : IDLValue :: try_from_candid_type ( config)
316+ . unwrap ( )
317+ . to_string ( )
318+ . as_bytes ( )
319+ . to_vec ( ) ,
320+ encoding : ContentEncoding :: Identity ,
321+ content_type : ContentType :: TXT ,
322+ } ) ;
323+
350324 // Add .well-known/ic-domains for custom domain support
351325 let ic_domains_content = b"identity.internetcomputer.org\n beta.identity.ic0.app\n beta.identity.internetcomputer.org\n id.ai\n beta.id.ai\n www.id.ai" . to_vec ( ) ;
352326 assets. push ( AssetUtilAsset {
@@ -375,18 +349,14 @@ fn get_static_assets(config: &InternetIdentityFrontendInit) -> Vec<AssetUtilAsse
375349}
376350
377351/// Fix up HTML pages by injecting canister ID and canister config
378- fn fixup_html ( html : & str , config : & InternetIdentityFrontendInit ) -> String {
379- // The backend canister ID is now included in the config, but we also set data-canister-id for backward compatibility.
380- let ( Some ( backend_canister_id) , Some ( backend_origin) ) =
381- ( & config. backend_canister_id , & config. backend_origin )
382- else {
383- return MISSING_MANDATORY_INTERNET_IDENTITY_FRONTEND_INSTALL_ARGS_HTML_ERROR . to_string ( ) ;
384- } ;
352+ fn fixup_html ( html : & str , config : & InternetIdentityFrontendArgs ) -> String {
353+ let backend_canister_id = config. backend_canister_id ;
354+ let backend_origin = config. backend_origin . clone ( ) ;
385355
386356 let html = html. replace (
387357 "</head>" ,
388358 & format ! (
389- r#"<link rel="preload" href="{backend_origin}/.config.did.bin" as="fetch"></head>"# ,
359+ r#"<link rel="preload" href="{backend_origin}/.config.did.bin" crossorigin="anonymous" fetchpriority="high" as="fetch"></head>"# ,
390360 ) ,
391361 ) ;
392362
@@ -395,10 +365,11 @@ fn fixup_html(html: &str, config: &InternetIdentityFrontendInit) -> String {
395365 let config = InternetIdentityInit :: from ( config. clone ( ) ) ;
396366 let encoded_config = BASE64 . encode ( Encode ! ( & config) . unwrap ( ) ) ;
397367
368+ // The backend canister ID is now included in the config, but we also set data-canister-id for backward compatibility.
398369 let html = html. replace (
399370 r#"<body "# ,
400371 & format ! (
401- r#"<body data-canister-id="{backend_canister_id}" data-canister-config="{encoded_config}" "#
372+ r#"<body data-canister-id="{backend_canister_id}" data-canister-config="{encoded_config}" "# ,
402373 ) ,
403374 ) ;
404375
0 commit comments