diff --git a/payjoin-cli/src/app/v2.rs b/payjoin-cli/src/app/v2.rs index 6eed9ef5..40740065 100644 --- a/payjoin-cli/src/app/v2.rs +++ b/payjoin-cli/src/app/v2.rs @@ -84,7 +84,7 @@ impl AppTrait for App { self.config.pj_directory.clone(), ohttp_keys.clone(), self.config.ohttp_relay.clone(), - std::time::Duration::from_secs(60 * 60), + Some(std::time::Duration::from_secs(60 * 60)), ); let (req, ctx) = initializer.extract_req().map_err(|e| anyhow!("Failed to extract request {}", e))?; diff --git a/payjoin/src/receive/v2/mod.rs b/payjoin/src/receive/v2/mod.rs index 13cb0623..1b17aaf9 100644 --- a/payjoin/src/receive/v2/mod.rs +++ b/payjoin/src/receive/v2/mod.rs @@ -215,7 +215,7 @@ impl ActiveSession { self.context.address.clone(), self.pj_url(), Some(self.context.ohttp_keys.clone()), - None, + Some(self.context.expiry), ) } diff --git a/payjoin/tests/integration.rs b/payjoin/tests/integration.rs index 758ec0fa..da9613f6 100644 --- a/payjoin/tests/integration.rs +++ b/payjoin/tests/integration.rs @@ -344,6 +344,24 @@ mod integration { } } + // #[tokio::test] + // async fn test_expiration() { + // std::env::set_var("RUST_LOG", "debug"); + // init_tracing(); + // let (cert, key) = local_cert_key(); + // let ohttp_relay_port = find_free_port(); + // let ohttp_relay = + // Url::parse(&format!("http://localhost:{}", ohttp_relay_port)).unwrap(); + // let directory_port = find_free_port(); + // let directory = Url::parse(&format!("https://localhost:{}", directory_port)).unwrap(); + // let gateway_origin = http::Uri::from_str(directory.as_str()).unwrap(); + // tokio::select!( + // _ = ohttp_relay::listen_tcp(ohttp_relay_port, gateway_origin) => assert!(false, "Ohttp relay is long running"), + // _ = init_directory(directory_port, (cert.clone(), key)) => assert!(false, "Directory server is long running"), + // res = do_v2_send_receive(ohttp_relay, directory, cert) => assert!(res.is_ok(), "v2 send receive failed: {:#?}", res) + // ); + // } + #[tokio::test] async fn v2_to_v2() { std::env::set_var("RUST_LOG", "debug"); @@ -376,16 +394,29 @@ mod integration { // ********************** // Inside the Receiver: let address = receiver.get_new_address(None, None)?.assume_checked(); + + // test session with expiry in the past let mut session = initialize_session( - address, + address.clone(), + directory.clone(), + ohttp_keys.clone(), + cert_der.clone(), + Some(Duration::from_secs(0)), + ) + .await?; + assert!(session.extract_req().is_err(), "Expired session should error"); + + // test session with expiry in the future + let mut session = initialize_session( + address.clone(), directory.clone(), ohttp_keys.clone(), cert_der.clone(), + None, ) .await?; println!("session: {:#?}", &session); let pj_uri_string = session.pj_uri_builder().build().to_string(); - // Poll receive request let (req, ctx) = session.extract_req()?; let response = agent.post(req.url).body(req.body).send().await?; @@ -404,6 +435,21 @@ mod integration { .check_pj_supported() .unwrap(); let psbt = build_original_psbt(&sender, &pj_uri)?; + // Test that an expired pj_url errors + let expired_pj_uri = payjoin::PjUriBuilder::new( + address, + directory.clone(), + Some(ohttp_keys.clone()), + Some(std::time::SystemTime::now()), + ) + .build(); + let mut expired_req_ctx = + RequestBuilder::from_psbt_and_uri(psbt.clone(), expired_pj_uri)? + .build_non_incentivizing()?; + assert!( + expired_req_ctx.extract_v2(directory.to_owned()).is_err(), + "Expired pj_uri should error" + ); let mut req_ctx = RequestBuilder::from_psbt_and_uri(psbt.clone(), pj_uri.clone())? .build_with_additional_fee( Amount::from_sat(10000), @@ -492,9 +538,14 @@ mod integration { .await?; let address = receiver.get_new_address(None, None)?.assume_checked(); - let mut session = - initialize_session(address, directory, ohttp_keys.clone(), cert_der.clone()) - .await?; + let mut session = initialize_session( + address, + directory, + ohttp_keys.clone(), + cert_der.clone(), + None, + ) + .await?; let pj_uri_string = session.pj_uri_builder().build().to_string(); @@ -614,6 +665,7 @@ mod integration { directory: Url, ohttp_keys: OhttpKeys, cert_der: Vec, + custom_expire_after: Option, ) -> Result { let mock_ohttp_relay = directory.clone(); // pass through to directory let mut initializer = SessionInitializer::new( @@ -621,7 +673,7 @@ mod integration { directory.clone(), ohttp_keys, mock_ohttp_relay.clone(), - Some(Duration::from_secs(60)), + custom_expire_after, ); let (req, ctx) = initializer.extract_req()?; println!("enroll req: {:#?}", &req);