lox_wasm/
lib.rs

1use chrono::Utc;
2use julianday::JulianDay;
3use lox_library::cred::{Invitation, Migration};
4use lox_library::proto::{
5    blockage_migration, check_blockage, issue_invite, level_up, migration, open_invite,
6    redeem_invite, trust_promotion,
7};
8use std::panic;
9use wasm_bindgen::prelude::*;
10
11// Returns today's Julian date as a u32 value
12fn today() -> u32 {
13    let naive_now = Utc::now().date_naive();
14    JulianDay::from(naive_now).inner().try_into().unwrap()
15}
16
17#[wasm_bindgen]
18extern "C" {
19    #[wasm_bindgen(js_namespace = console)]
20    pub fn log(s: &str);
21}
22
23#[wasm_bindgen]
24pub fn set_panic_hook() {
25    panic::set_hook(Box::new(console_error_panic_hook::hook));
26}
27
28// Receives an invite and prepares an open_invite request, returning the
29// Request and State
30#[wasm_bindgen]
31pub fn open_invite(invite: &[u8]) -> Result<String, JsValue> {
32    log(&format!("Using invite: {:?}", invite));
33    let token = match lox_utils::validate(invite) {
34        Ok(token) => token,
35        Err(e) => return Err(JsValue::from(e.to_string())),
36    };
37    let (request, state) = open_invite::request(&token);
38    let req_state = lox_utils::OpenReqState { request, state };
39    log(&format!(
40        "Formatted open invite request: {}",
41        serde_json::to_string(&req_state).unwrap()
42    ));
43    Ok(serde_json::to_string(&req_state).unwrap())
44}
45
46#[wasm_bindgen]
47pub fn handle_new_lox_credential(
48    open_lox_result: String,
49    open_lox_response: String,
50    lox_pub: String,
51) -> Result<String, JsValue> {
52    let req_state: lox_utils::OpenReqState = serde_json::from_str(&open_lox_result).unwrap();
53    let deserialized_state = req_state.state;
54    let deserialized_response = serde_json::from_str(&open_lox_response).unwrap();
55    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
56    let lox_cred = match open_invite::handle_response(
57        deserialized_state,
58        deserialized_response,
59        &pubkeys.lox_pub,
60    ) {
61        Ok(lox_cred) => lox_cred,
62        Err(e) => {
63            log(&format!("Error: {:?}", e.to_string()));
64            return Err(JsValue::from(e.to_string()));
65        }
66    };
67    let lox_cred = lox_utils::LoxCredential {
68        lox_credential: lox_cred.0,
69        bridgeline: Some(lox_cred.1),
70        invitation: None,
71    };
72    log(&format!(
73        "Got new Lox Credential: {}",
74        serde_json::to_string(&lox_cred.lox_credential).unwrap()
75    ));
76    log(&format!(
77        "Got new bridgeline: {}",
78        serde_json::to_string(&lox_cred.bridgeline).unwrap()
79    ));
80    Ok(serde_json::to_string(&lox_cred).unwrap())
81}
82
83#[wasm_bindgen]
84pub fn trust_promotion(open_lox_cred: String, lox_pub: String) -> Result<String, JsValue> {
85    let lox_cred: lox_utils::LoxCredential = serde_json::from_str(&open_lox_cred).unwrap();
86    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
87    let tp_result =
88        match trust_promotion::request(&lox_cred.lox_credential, &pubkeys.lox_pub, today()) {
89            Ok(tp_result) => tp_result,
90            Err(e) => {
91                log(&format!("Error: {:?}", e.to_string()));
92                return Err(JsValue::from(e.to_string()));
93            }
94        };
95    let req_state = lox_utils::TrustReqState {
96        request: tp_result.0,
97        state: tp_result.1,
98    };
99    log(&format!(
100        "Formatted Trust Promotion request: {}",
101        serde_json::to_string(&req_state).unwrap()
102    ));
103    Ok(serde_json::to_string(&req_state).unwrap())
104}
105
106#[wasm_bindgen]
107pub fn handle_trust_promotion(
108    trust_promo_request: String,
109    trust_promo_response: String,
110) -> Result<String, JsValue> {
111    let req_state: lox_utils::TrustReqState = serde_json::from_str(&trust_promo_request).unwrap();
112    let deserialized_state = req_state.state;
113    let deserialized_response = serde_json::from_str(&trust_promo_response).unwrap();
114    let migration_cred =
115        match trust_promotion::handle_response(deserialized_state, deserialized_response) {
116            Ok(migration_cred) => migration_cred,
117            Err(e) => {
118                log(&format!("Error: {:?}", e.to_string()));
119                return Err(JsValue::from(e.to_string()));
120            }
121        };
122    log(&format!(
123        "Got new Migration Credential: {}",
124        serde_json::to_string(&migration_cred).unwrap()
125    ));
126    Ok(serde_json::to_string(&migration_cred).unwrap())
127}
128
129#[wasm_bindgen]
130pub fn trust_migration(
131    open_lox_cred: String,
132    trust_promo_cred: String,
133    lox_pub: String,
134) -> Result<String, JsValue> {
135    let lox_cred: lox_utils::LoxCredential = serde_json::from_str(&open_lox_cred).unwrap();
136    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
137    let mig_cred: Migration = serde_json::from_str(&trust_promo_cred).unwrap();
138    let tm_result = match migration::request(
139        &lox_cred.lox_credential,
140        &mig_cred,
141        &pubkeys.lox_pub,
142        &pubkeys.migration_pub,
143    ) {
144        Ok(tm_result) => tm_result,
145        Err(e) => {
146            log(&format!("Error: {:?}", e.to_string()));
147            return Err(JsValue::from(e.to_string()));
148        }
149    };
150    let req_state = lox_utils::MigReqState {
151        request: tm_result.0,
152        state: tm_result.1,
153    };
154    log(&format!(
155        "Formatted Trust Migration request: {}",
156        serde_json::to_string(&req_state).unwrap()
157    ));
158    Ok(serde_json::to_string(&req_state).unwrap())
159}
160
161#[wasm_bindgen]
162pub fn handle_trust_migration(
163    trust_migration_request: String,
164    trust_migration_response: String,
165    lox_pub: String,
166) -> Result<String, JsValue> {
167    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
168    let req_state: lox_utils::MigReqState = serde_json::from_str(&trust_migration_request).unwrap();
169    let deserialized_state = req_state.state;
170    let deserialized_response = serde_json::from_str(&trust_migration_response).unwrap();
171    let level_one_cred = match migration::handle_response(
172        deserialized_state,
173        deserialized_response,
174        &pubkeys.lox_pub,
175    ) {
176        Ok(level_1_cred) => lox_utils::LoxCredential {
177            lox_credential: level_1_cred,
178            bridgeline: None,
179            invitation: None,
180        },
181        Err(e) => {
182            log(&format!("Error: {:?}", e.to_string()));
183            return Err(JsValue::from(e.to_string()));
184        }
185    };
186    log(&format!(
187        "Got new Level 1 Credential: {}",
188        serde_json::to_string(&level_one_cred).unwrap()
189    ));
190    Ok(serde_json::to_string(&level_one_cred).unwrap())
191}
192
193#[wasm_bindgen]
194pub fn level_up(
195    level_one_cred: String,
196    encrypted_table: String,
197    lox_pub: String,
198) -> Result<String, JsValue> {
199    let lox_cred: lox_utils::LoxCredential = serde_json::from_str(&level_one_cred).unwrap();
200    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
201    let reach_cred =
202        lox_utils::generate_reachability_cred(&lox_cred.lox_credential, encrypted_table);
203
204    let lu_result = match level_up::request(
205        &lox_cred.lox_credential,
206        &reach_cred,
207        &pubkeys.lox_pub,
208        &pubkeys.reachability_pub,
209        today(),
210    ) {
211        Ok(lu_result) => lu_result,
212        Err(e) => {
213            log(&format!("Error: {:?}", e.to_string()));
214            return Err(JsValue::from(e.to_string()));
215        }
216    };
217    let req_state = lox_utils::LevelupReqState {
218        request: lu_result.0,
219        state: lu_result.1,
220    };
221    log(&format!(
222        "Formatted Level Up request: {}",
223        serde_json::to_string(&req_state).unwrap()
224    ));
225    Ok(serde_json::to_string(&req_state).unwrap())
226}
227
228#[wasm_bindgen]
229pub fn handle_level_up(
230    levelup_request: String,
231    levelup_response: String,
232    lox_pub: String,
233) -> Result<String, JsValue> {
234    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
235    let req_state: lox_utils::LevelupReqState = serde_json::from_str(&levelup_request).unwrap();
236    let deserialized_state = req_state.state;
237    let deserialized_response = serde_json::from_str(&levelup_response).unwrap();
238    let level_up_cred = match level_up::handle_response(
239        deserialized_state,
240        deserialized_response,
241        &pubkeys.lox_pub,
242    ) {
243        Ok(level_up_cred) => lox_utils::LoxCredential {
244            lox_credential: level_up_cred,
245            bridgeline: None,
246            invitation: None,
247        },
248        Err(e) => {
249            log(&format!("Error: {:?}", e.to_string()));
250            return Err(JsValue::from(e.to_string()));
251        }
252    };
253    log(&format!(
254        "Got new Level Up Credential: {}",
255        serde_json::to_string(&level_up_cred).unwrap()
256    ));
257    Ok(serde_json::to_string(&level_up_cred).unwrap())
258}
259
260#[wasm_bindgen]
261pub fn issue_invite(
262    trusted_cred: String,
263    encrypted_table: String,
264    lox_pub: String,
265) -> Result<String, JsValue> {
266    let lox_cred: lox_utils::LoxCredential = serde_json::from_str(&trusted_cred).unwrap();
267    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
268    let reach_cred =
269        lox_utils::generate_reachability_cred(&lox_cred.lox_credential, encrypted_table);
270
271    let issue_result = match issue_invite::request(
272        &lox_cred.lox_credential,
273        &reach_cred,
274        &pubkeys.lox_pub,
275        &pubkeys.reachability_pub,
276        today(),
277    ) {
278        Ok(issue_result) => issue_result,
279        Err(e) => {
280            log(&format!("Error: {:?}", e.to_string()));
281            return Err(JsValue::from(e.to_string()));
282        }
283    };
284    let req_state = lox_utils::IssueInviteReqState {
285        request: issue_result.0,
286        state: issue_result.1,
287    };
288    log(&format!(
289        "Formatted Issue Invite request: {}",
290        serde_json::to_string(&req_state).unwrap()
291    ));
292    Ok(serde_json::to_string(&req_state).unwrap())
293}
294
295#[wasm_bindgen]
296pub fn handle_issue_invite(
297    issue_invite_request: String,
298    issue_invite_response: String,
299    lox_pub: String,
300) -> Result<String, JsValue> {
301    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
302    let req_state: lox_utils::IssueInviteReqState =
303        serde_json::from_str(&issue_invite_request).unwrap();
304    let deserialized_state = req_state.state;
305    let deserialized_response = serde_json::from_str(&issue_invite_response).unwrap();
306    let issue_invite_cred = match issue_invite::handle_response(
307        deserialized_state,
308        deserialized_response,
309        &pubkeys.lox_pub,
310        &pubkeys.invitation_pub,
311    ) {
312        Ok(issue_invite_cred) => issue_invite_cred,
313        Err(e) => {
314            log(&format!("Error: {:?}", e.to_string()));
315            return Err(JsValue::from(e.to_string()));
316        }
317    };
318    let invitation_cred = lox_utils::LoxCredential {
319        lox_credential: issue_invite_cred.0,
320        bridgeline: None,
321        invitation: Some(issue_invite_cred.1),
322    };
323
324    log(&format!(
325        "Got new Invitation Credential and Lox Credential: {}",
326        serde_json::to_string(&invitation_cred).unwrap()
327    ));
328    Ok(serde_json::to_string(&invitation_cred).unwrap())
329}
330
331// Separate Trusted Invite from credential prior to passing it to friend
332#[wasm_bindgen]
333pub fn prepare_invite(invitation_cred: String) -> String {
334    let cred: lox_utils::LoxCredential = serde_json::from_str(&invitation_cred).unwrap();
335    log(&format!(
336        "Prepared Invitation: {}",
337        serde_json::to_string(&cred.invitation).unwrap()
338    ));
339    serde_json::to_string(&cred.invitation).unwrap()
340}
341
342//
343#[wasm_bindgen]
344pub fn redeem_invite(invitation: String, lox_pub: String) -> Result<String, JsValue> {
345    let invitation_cred: Invitation = serde_json::from_str(&invitation).unwrap();
346    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
347    let redeem_result =
348        match redeem_invite::request(&invitation_cred, &pubkeys.invitation_pub, today()) {
349            Ok(redeem_result) => redeem_result,
350            Err(e) => {
351                log(&format!("Error: {:?}", e.to_string()));
352                return Err(JsValue::from(e.to_string()));
353            }
354        };
355    let req_state = lox_utils::RedeemReqState {
356        request: redeem_result.0,
357        state: redeem_result.1,
358    };
359    log(&format!(
360        "Formatted Redeem Invite request: {}",
361        serde_json::to_string(&req_state).unwrap()
362    ));
363    Ok(serde_json::to_string(&req_state).unwrap())
364}
365
366#[wasm_bindgen]
367pub fn handle_redeem_invite(
368    redeem_invite_request: String,
369    redeem_invite_response: String,
370    lox_pub: String,
371) -> Result<String, JsValue> {
372    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
373    let req_state: lox_utils::RedeemReqState =
374        serde_json::from_str(&redeem_invite_request).unwrap();
375    let deserialized_state = req_state.state;
376    let deserialized_response = serde_json::from_str(&redeem_invite_response).unwrap();
377    let redeem_invite_cred = match redeem_invite::handle_response(
378        deserialized_state,
379        deserialized_response,
380        &pubkeys.lox_pub,
381    ) {
382        Ok(issue_invite_cred) => lox_utils::LoxCredential {
383            lox_credential: issue_invite_cred,
384            bridgeline: None,
385            invitation: None,
386        },
387        Err(e) => {
388            log(&format!("Error: {:?}", e.to_string()));
389            return Err(JsValue::from(e.to_string()));
390        }
391    };
392    log(&format!(
393        "Got new Trusted Lox Credential from Invitation: {}",
394        serde_json::to_string(&redeem_invite_cred).unwrap()
395    ));
396    Ok(serde_json::to_string(&redeem_invite_cred).unwrap())
397}
398
399#[wasm_bindgen]
400pub fn check_blockage(lox_cred: String, lox_pub: String) -> Result<String, JsValue> {
401    let lox: lox_utils::LoxCredential = serde_json::from_str(&lox_cred).unwrap();
402    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
403    let cb_result = match check_blockage::request(&lox.lox_credential, &pubkeys.lox_pub) {
404        Ok(cb_result) => cb_result,
405        Err(e) => {
406            log(&format!("Error: {:?}", e.to_string()));
407            return Err(JsValue::from(e.to_string()));
408        }
409    };
410    let req_state = lox_utils::CheckBlockageReqState {
411        request: cb_result.0,
412        state: cb_result.1,
413    };
414    log(&format!(
415        "Formatted Check Blockage request: {}",
416        serde_json::to_string(&req_state).unwrap()
417    ));
418    Ok(serde_json::to_string(&req_state).unwrap())
419}
420
421#[wasm_bindgen]
422pub fn handle_check_blockage(
423    check_blockage_request: String,
424    check_blockage_response: String,
425) -> Result<String, JsValue> {
426    let req_state: lox_utils::CheckBlockageReqState =
427        serde_json::from_str(&check_blockage_request).unwrap();
428    let deserialized_state = req_state.state;
429    let deserialized_response = serde_json::from_str(&check_blockage_response).unwrap();
430    let migration_cred =
431        match check_blockage::handle_response(deserialized_state, deserialized_response) {
432            Ok(migration_cred) => migration_cred,
433            Err(e) => {
434                log(&format!("Error: {:?}", e.to_string()));
435                return Err(JsValue::from(e.to_string()));
436            }
437        };
438    log(&format!(
439        "Got new Blockage Migration Credential: {}",
440        serde_json::to_string(&migration_cred).unwrap()
441    ));
442    Ok(serde_json::to_string(&migration_cred).unwrap())
443}
444
445#[wasm_bindgen]
446pub fn blockage_migration(
447    lox_cred: String,
448    check_migration_cred: String,
449    lox_pub: String,
450) -> Result<String, JsValue> {
451    let lox_cred: lox_utils::LoxCredential = serde_json::from_str(&lox_cred).unwrap();
452    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
453    let mig_cred: Migration = serde_json::from_str(&check_migration_cred).unwrap();
454    let bm_result = match blockage_migration::request(
455        &lox_cred.lox_credential,
456        &mig_cred,
457        &pubkeys.lox_pub,
458        &pubkeys.migration_pub,
459    ) {
460        Ok(bm_result) => bm_result,
461        Err(e) => {
462            log(&format!("Error: {:?}", e.to_string()));
463            return Err(JsValue::from(e.to_string()));
464        }
465    };
466    let req_state = lox_utils::BlockageMigReqState {
467        request: bm_result.0,
468        state: bm_result.1,
469    };
470    log(&format!(
471        "Formatted Blockage Migration request: {}",
472        serde_json::to_string(&req_state).unwrap()
473    ));
474    Ok(serde_json::to_string(&req_state).unwrap())
475}
476
477#[wasm_bindgen]
478pub fn handle_blockage_migration(
479    blockage_migration_request: String,
480    blockage_migration_response: String,
481    lox_pub: String,
482) -> Result<String, JsValue> {
483    let pubkeys: lox_utils::PubKeys = serde_json::from_str(&lox_pub).unwrap();
484    let req_state: lox_utils::BlockageMigReqState =
485        serde_json::from_str(&blockage_migration_request).unwrap();
486    let deserialized_state = req_state.state;
487    let deserialized_response = serde_json::from_str(&blockage_migration_response).unwrap();
488    let lox_cred = match blockage_migration::handle_response(
489        deserialized_state,
490        deserialized_response,
491        &pubkeys.lox_pub,
492    ) {
493        Ok(lox_cred) => lox_utils::LoxCredential {
494            lox_credential: lox_cred,
495            bridgeline: None,
496            invitation: None,
497        },
498        Err(e) => {
499            log(&format!("Error: {:?}", e.to_string()));
500            return Err(JsValue::from(e.to_string()));
501        }
502    };
503    log(&format!(
504        "Got new Lox Credential after Migration: {}",
505        serde_json::to_string(&lox_cred).unwrap()
506    ));
507    Ok(serde_json::to_string(&lox_cred).unwrap())
508}