From 8faf4fc2736e2c39aa6d28aaeb25e9f8bcfd8485 Mon Sep 17 00:00:00 2001 From: onyinyang Date: Mon, 27 Feb 2023 14:17:26 -0500 Subject: [PATCH] Add redeem invite --- crates/lox-wasm/index.js | 18 +++++++- crates/lox-wasm/src/lib.rs | 95 +++++++++++++++++++++++++++++++++++--- 2 files changed, 105 insertions(+), 8 deletions(-) diff --git a/crates/lox-wasm/index.js b/crates/lox-wasm/index.js index 99ac848..e380140 100644 --- a/crates/lox-wasm/index.js +++ b/crates/lox-wasm/index.js @@ -9,6 +9,9 @@ import init, { handle_level_up, issue_invite, handle_issue_invite, + prepare_invite, + redeem_invite, + handle_redeem_invite, set_panic_hook } from "./pkg/lox_wasm.js"; let pubkeys = await simple_request("/pubkeys"); console.log("Got pubkeys: " + pubkeys); @@ -109,7 +112,7 @@ encrypted_table = await simple_request("/reachability"); console.log("Got Encrypted Table: " + encrypted_table); let requested_issue_invitation = issue_invite(level_four_cred, encrypted_table, pubkeys); -// Issue an Invitation for a friend +// Issue an Invitation cred let issue_invite_cred = await init().then(() => { set_panic_hook(); let cred = requested_cred("/issueinvite", requested_issue_invitation).then((response)=> { @@ -119,6 +122,19 @@ let issue_invite_cred = await init().then(() => { return cred; }); +let prepare_invitation = prepare_invite(issue_invite_cred); +// Trusted Invitation Request +let requested_invitation = redeem_invite(prepare_invitation, pubkeys); +// Issue an Invitation cred +let lox_cred_from_invite = await init().then(() => { + set_panic_hook(); + let cred = requested_cred("/redeem", requested_invitation).then((response)=> { + console.log("Got new Invite and Lox Credential: " + response); + return handle_redeem_invite(requested_invitation, response, pubkeys); + }); + return cred; + }); + function requested_cred(command, requested) { return new Promise((fulfill, reject) => { diff --git a/crates/lox-wasm/src/lib.rs b/crates/lox-wasm/src/lib.rs index 4dfeeba..e838538 100644 --- a/crates/lox-wasm/src/lib.rs +++ b/crates/lox-wasm/src/lib.rs @@ -3,7 +3,7 @@ use std::sync::atomic::{AtomicI64, Ordering}; use julianday::JulianDay; use lazy_static::lazy_static; use lox::bridge_table::{BridgeLine,from_scalar,BridgeTable, ENC_BUCKET_BYTES}; -use lox::cred::{BucketReachability, Lox, Migration}; +use lox::cred::{BucketReachability, Invitation, Lox, Migration}; use lox::proto::{open_invite, trust_promotion, migration, level_up, issue_invite, redeem_invite, check_blockage, blockage_migration}; use lox::{IssuerPubKey, OPENINV_LENGTH, scalar_u32}; @@ -47,6 +47,12 @@ struct IssueInviteReqState { state: issue_invite::State, } +#[derive(Deserialize, Serialize)] +struct RedeemReqState { + request: redeem_invite::Request, + state: redeem_invite::State, +} + #[derive(Debug, Deserialize, Serialize)] struct PubKeys { lox_pub: IssuerPubKey, @@ -64,11 +70,16 @@ pub struct EncBridgeTable { } #[derive(Debug, Deserialize, Serialize)] -struct Credential { +struct OpenCredential { lox_credential: Lox, bridgeline: BridgeLine, } +#[derive(Debug, Deserialize, Serialize)] +struct InviteCredential { + lox_credential: Lox, + invitation: Invitation, +} fn today() -> u32 { let naive_now = Utc::now().date_naive(); @@ -154,7 +165,7 @@ pub fn handle_new_lox_credential( return Err(JsValue::from(e.to_string())); } }; - let lox_cred = Credential { + let lox_cred = OpenCredential { lox_credential: lox_cred.0, bridgeline: lox_cred.1, }; @@ -173,7 +184,7 @@ pub fn handle_new_lox_credential( #[wasm_bindgen] pub fn trust_promotion(open_lox_cred: String, lox_pub: String) -> Result { - let lox_cred: Credential = serde_json::from_str(&open_lox_cred).unwrap(); + let lox_cred: OpenCredential = serde_json::from_str(&open_lox_cred).unwrap(); let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap(); // To test creation of the credential we need to advance the day to 30 // in production this should just use the today() function @@ -230,7 +241,7 @@ pub fn handle_trust_promotion( #[wasm_bindgen] pub fn trust_migration(open_lox_cred: String, trust_promo_cred: String, lox_pub: String) -> Result { - let lox_cred: Credential = serde_json::from_str(&open_lox_cred).unwrap(); + let lox_cred: OpenCredential = serde_json::from_str(&open_lox_cred).unwrap(); let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap(); let mig_cred: Migration = serde_json::from_str(&trust_promo_cred).unwrap(); let tm_result = @@ -406,15 +417,85 @@ pub fn handle_issue_invite( return Err(JsValue::from(e.to_string())); } }; + let invitation_cred = InviteCredential { + lox_credential: issue_invite_cred.0, + invitation: issue_invite_cred.1, + }; + unsafe { log(&format!( "Got new Invitation Credential and Lox Credential: {}", - serde_json::to_string(&issue_invite_cred).unwrap() + serde_json::to_string(&invitation_cred).unwrap() )); } - Ok(serde_json::to_string(&issue_invite_cred).unwrap()) + Ok(serde_json::to_string(&invitation_cred).unwrap()) } +// Separate Trusted Invite from credential prior to passing it to friend +#[wasm_bindgen] +pub fn prepare_invite(invitation_cred: String) -> String { + let cred: InviteCredential = serde_json::from_str(&invitation_cred).unwrap(); + log(&format!( + "Prepared Invitation: {}", + serde_json::to_string(&cred.invitation).unwrap() + )); + serde_json::to_string(&cred.invitation).unwrap() +} + +// +#[wasm_bindgen] +pub fn redeem_invite(invitation: String, lox_pub: String) -> Result { + let invitation_cred: Invitation = serde_json::from_str(&invitation).unwrap(); + let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap(); + let redeem_result = + match redeem_invite::request(&invitation_cred, &pubkeys.invitation_pub, test_today(371)) { + Ok(redeem_result) => redeem_result, + Err(e) => { + log(&format!("Error: {:?}", e.to_string())); + return Err(JsValue::from(e.to_string())); + } + }; + let req_state = RedeemReqState { + request: redeem_result.0, + state: redeem_result.1, + }; + unsafe { + log(&format!( + "Formatted Redeem Invite request: {}", + serde_json::to_string(&req_state).unwrap() + )); + } + Ok(serde_json::to_string(&req_state).unwrap()) +} + +#[wasm_bindgen] +pub fn handle_redeem_invite( + redeem_invite_request: String, + redeem_invite_response: String, + lox_pub: String +) -> Result { + let pubkeys: PubKeys = serde_json::from_str(&lox_pub).unwrap(); + let req_state: RedeemReqState = serde_json::from_str(&redeem_invite_request).unwrap(); + let deserialized_state = req_state.state; + let deserialized_response = serde_json::from_str(&redeem_invite_response).unwrap(); + let redeem_invite_cred = + match redeem_invite::handle_response(deserialized_state, deserialized_response, &pubkeys.lox_pub) { + Ok(issue_invite_cred) => issue_invite_cred, + Err(e) => { + log(&format!("Error: {:?}", e.to_string())); + return Err(JsValue::from(e.to_string())); + } + }; + unsafe { + log(&format!( + "Got new Trusted Lox Credential from Invitation: {}", + serde_json::to_string(&redeem_invite_cred).unwrap() + )); + } + Ok(serde_json::to_string(&redeem_invite_cred).unwrap()) +} + + // This should also check the pubkey fn validate(invite: &[u8]) -> Result<[u8; OPENINV_LENGTH], TryFromSliceError> { invite.try_into()