fix broker choice when creating wallet on public BSP

pull/19/head
Niko PLP 1 year ago
parent b32b687951
commit b549e843ac
  1. 48
      ng-app/src/routes/WalletCreate.svelte
  2. 4
      ng-wallet/src/types.rs
  3. 75
      ngaccount/web/src/routes/Create.svelte
  4. 9
      ngd/README.md
  5. 2
      ngd/src/main.rs
  6. 17
      p2p-broker/src/server_ws.rs
  7. 74
      p2p-net/src/types.rs
  8. 17
      p2p-net/src/utils.rs

@ -109,6 +109,7 @@
let cloud_link;
let animateDownload = true;
let invitation;
let pre_invitation;
let unsub_register_accepted;
let unsub_register_error;
@ -159,7 +160,10 @@
param.get("i")
);
console.log(invitation);
if (!invitation) {
if (invitation && invitation.V0.url) {
pre_invitation = invitation;
invitation = undefined;
} else if (!invitation) {
let redirect = await ng.get_ngone_url_of_invitation(param.get("i"));
if (redirect) {
console.error("got an invitation for another broker. redirecting");
@ -169,6 +173,11 @@
console.error("invalid invitation. ignoring it");
}
}
} else {
pre_invitation = await ng.get_local_bootstrap_with_public(
location.href
);
console.log("pre_invitation", pre_invitation);
}
}
scrollToTop();
@ -176,10 +185,11 @@
function create_wallet() {
intro = false;
if (invitation && invitation.V0.url) {
// we redirect to the TOS url of the invitation.
window.location.href = invitation.V0.url;
}
// if (invitation && invitation.V0.url) {
// // we redirect to the TOS url of the invitation.
// wait = "Redirecting to TOS";
// window.location.href = invitation.V0.url;
// }
scrollToTop();
}
@ -890,6 +900,33 @@
<h2 class="mt-3 text-xl">Please choose one broker among the list</h2>
</div>
</div>
{#if pre_invitation}
<div class="row mt-5">
<button
on:click|once={async () => {
await select_bsp(pre_invitation.V0.url, pre_invitation.V0.name);
}}
class="choice-button text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:outline-none focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
class="mr-4 block h-10 w-10"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418"
/>
</svg>
Register with {pre_invitation.V0.name || "this broker"}
</button>
</div>
{:else}
<div class="row mt-5">
<button
on:click|once={selectEU}
@ -923,6 +960,7 @@
For the rest of the world
</button>
</div>
{/if}
<div class="row mt-5">
<button

@ -113,7 +113,7 @@ pub struct LocalWalletStorageV0 {
impl From<&CreateWalletResultV0> for LocalWalletStorageV0 {
fn from(res: &CreateWalletResultV0) -> Self {
LocalWalletStorageV0 {
bootstrap: BootstrapContent::V0(BootstrapContentV0 { servers: vec![] }),
bootstrap: BootstrapContent::V0(BootstrapContentV0::new()),
wallet: res.wallet.clone(),
client: res.client.priv_key.to_pub(),
}
@ -123,7 +123,7 @@ impl From<&CreateWalletResultV0> for LocalWalletStorageV0 {
impl LocalWalletStorageV0 {
pub fn new(wallet: Wallet, client: ClientV0) -> Self {
LocalWalletStorageV0 {
bootstrap: BootstrapContent::V0(BootstrapContentV0 { servers: vec![] }),
bootstrap: BootstrapContent::V0(BootstrapContentV0::new()),
wallet,
client: client.priv_key.to_pub(),
}

@ -22,6 +22,7 @@
const param = new URLSearchParams($querystring);
let ca = param.get("ca");
let go_back = true;
let wait = false;
let top;
const api_url = import.meta.env.PROD
@ -29,6 +30,7 @@
: "http://192.168.192.2:3031/api/v1/";
async function register() {
wait = true;
const opts = {
method: "get",
};
@ -46,6 +48,7 @@
await success(result);
}
} catch (e) {
wait = false;
error = e.message;
}
}
@ -60,6 +63,7 @@
let window_api = await import("@tauri-apps/plugin-window");
let main = window_api.Window.getByLabel("main");
if (main) {
wait = true;
await main.emit("error", result);
} else {
await window_api.getCurrent().close();
@ -70,6 +74,7 @@
go_back = false;
window.location.href = result.url;
} else {
wait = true;
window.history.go(-1);
}
}
@ -103,7 +108,33 @@
};
</script>
<main class="container3" bind:this={top}>
{#if wait}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-primary-700">
Please wait...
<svg
class="animate-spin mt-10 h-14 w-14 mx-auto"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<circle
class="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
/>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
</div>
{:else}
<main class="container3" bind:this={top}>
<div class="row">
<Logo class="logo block h-24" alt="NextGraph Logo" />
{#if domain == "nextgraph.eu"}
@ -149,12 +180,14 @@
<div class=" max-w-6xl lg:px-8 mx-auto px-4">
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
You would like to choose <b>{domain}</b> as your Broker Service
Provider.<br />Please read carefully the Terms of Service here below,
before accepting them.
Provider.<br />Please read carefully the Terms of Service here
below, before accepting them.
</p>
</div>
{/if}
<div class="px-4 pt-5 mx-auto max-w-6xl lg:px-8 lg:pt-10 dark:bg-slate-800">
<div
class="px-4 pt-5 mx-auto max-w-6xl lg:px-8 lg:pt-10 dark:bg-slate-800"
>
<div class="max-w-xl md:mx-auto sm:text-center lg:max-w-2xl">
<h2 class="pb-5 text-xl">{domain} Terms of Service</h2>
@ -177,8 +210,8 @@
/>
</svg>
<span
>Our servers are located in Germany, and we comply with the GDPR
regulation.</span
>Our servers are located in Germany, and we comply with the
GDPR regulation.</span
>
</li>
<li class="flex space-x-3">
@ -218,8 +251,9 @@
</svg>
<span
>All the data you exchange with us while using the broker is
end-to-end encrypted and we do not have access to your decryption
keys, meaning that we cannot see the content of your documents.</span
end-to-end encrypted and we do not have access to your
decryption keys, meaning that we cannot see the content of your
documents.</span
>
</li>
<li class="flex space-x-3">
@ -241,16 +275,16 @@
<span
>We do not log any private information about you (nor IP, nor
country, nor statistics of any kind). Only your UserId is kept,
together with the list of devices (clientId) you use to connect to
the broker. We collect general purpose information about your
together with the list of devices (clientId) you use to connect
to the broker. We collect general purpose information about your
device (OS version, browser version, and if you use the app, the
version and date of last update). We do not have access to any
unique tracking identifier of your device (like Android MAID or
iPhone IDFA). We could nevertheless be asked by law enforcement
authorities, depending on the jurisdiction of the server, to log
the IP you use when connecting to the broker, and/or to provide
them with the encrypted content you have stored on our servers. If
you prefer to avoid that eventually, please refrain from any
them with the encrypted content you have stored on our servers.
If you prefer to avoid that eventually, please refrain from any
illegal activity while using this broker.</span
>
</li>
@ -274,8 +308,8 @@
You can delete your account with us at any time by going to the
link <a target="_blank" href="https://account.{domain}/#/delete"
>https://account.{domain}/#/delete</a
> or by entering in your NextGraph application and selecting the menu,
then Accounts, then under broker "delete registration"</span
> or by entering in your NextGraph application and selecting the
menu, then Accounts, then under broker "delete registration"</span
>
</li>
<li class="flex space-x-3">
@ -295,10 +329,12 @@
/>
</svg>
<span
>Registration is free of charge. And it would be very nice of you
if you wanted to donate a small amount to help us cover the fees
we have to pay for operating the servers. Here is the donation
link: <a target="_blank" href="https://nextgraph.org/donate"
>Registration is free of charge. And it would be very nice of
you if you wanted to donate a small amount to help us cover the
fees we have to pay for operating the servers. Here is the
donation link: <a
target="_blank"
href="https://nextgraph.org/donate"
>https://nextgraph.org/donate</a
>
</span>
@ -338,4 +374,5 @@
</div>
{/if}
{/if}
</main>
</main>
{/if}

@ -13,8 +13,13 @@ If you prefer to change the base directory, use the argument `--base [PATH]` whe
```
ngcli gen-key
ngd --save-key -d <DOMAIN_NAME> -l 1440 --admin <THE_USER_ID_YOU_JUST_CREATED>
// note the server peerID in the logs
ngd -v --save-key -d <DOMAIN_NAME> -l 1440 --admin <THE_USER_ID_YOU_JUST_CREATED>
// note the server peerID from the logs
```
in another terminal:
```
ngcli --save-key -s 127.0.0.1,1440,<PEER_ID_OF_SERVER> -u <THE_PRIVATE_KEY_OF_THE_USER_YOU_JUST_CREATED> admin add-user <THE_USER_ID_YOU_JUST_CREATED> -a
```

@ -996,7 +996,7 @@ async fn main_inner() -> Result<(), ()> {
config_path.to_str().unwrap()
);
log_info!(
"You not be able to use any Quick config options anymore on the command line at the next command-line start of the server. But you can go to modify the config file directly, or delete it.",
"You will not be able to use any Quick config options anymore on the command line at the next command-line start of the server. But you can go to modify the config file directly, or delete it.",
);
}
} else {

@ -656,6 +656,8 @@ pub async fn run_server_v0(
let mut servers: Vec<BrokerServerV0> = vec![];
let registration_url = config.registration_url;
// Preparing the listeners addrs and infos
for listener in config.listeners {
if !listener.accept_direct && listener.accept_forward_for == AcceptForwardForV0::No {
@ -757,8 +759,13 @@ pub async fn run_server_v0(
log_warn!("There isn't any listener that accept clients. This is a misconfiguration as a core server that cannot receive client connections is useless");
}
let bootstrap_v0 = BootstrapContentV0 { servers };
let bootstrap = BootstrapContent::V0(bootstrap_v0.clone());
BOOTSTRAP_STRING.set(json!(bootstrap).to_string()).unwrap();
let local_bootstrap_info = LocalBootstrapInfo::V0(LocalBootstrapInfoV0 {
bootstrap: bootstrap_v0.clone(),
registration_url: registration_url.clone(),
});
BOOTSTRAP_STRING
.set(json!(local_bootstrap_info).to_string())
.unwrap();
// saving the infos in the broker. This needs to happen before we start listening, as new incoming connections can happen anytime after that.
// and we need those infos for permission checking.
@ -772,7 +779,7 @@ pub async fn run_server_v0(
&mut path,
wallet_master_key,
if admin_invite {
Some(bootstrap_v0)
Some(bootstrap_v0.clone())
} else {
None
},
@ -788,9 +795,9 @@ pub async fn run_server_v0(
overlays_configs: config.overlays_configs,
registration: config.registration,
admin_user: config.admin_user,
registration_url: config.registration_url,
registration_url,
peer_id,
bootstrap,
bootstrap: BootstrapContent::V0(bootstrap_v0),
};
broker.set_server_config(server_config);
}

@ -546,6 +546,15 @@ impl BootstrapContentV0 {
pub fn get_first_peer_id(&self) -> Option<PubKey> {
self.servers.first().map(|s| s.peer_id)
}
pub fn get_domain(&self) -> Option<String> {
for server in self.servers.iter() {
if let BrokerServerTypeV0::Domain(name) = &server.server_type {
return Some(name.clone());
}
}
None
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
@ -561,6 +570,43 @@ impl BootstrapContent {
}
}
/// Local Bootstrap info Version 0, served at /.ng_bootstrap
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LocalBootstrapInfoV0 {
/// list of servers, in order of preference
pub bootstrap: BootstrapContentV0,
/// optional registration_url for public server that accept to be BSP for new clients
pub registration_url: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum LocalBootstrapInfo {
V0(LocalBootstrapInfoV0),
}
impl LocalBootstrapInfo {
pub fn servers(&self) -> &Vec<BrokerServerV0> {
match self {
Self::V0(v0) => &v0.bootstrap.servers,
}
}
}
impl From<LocalBootstrapInfo> for Invitation {
fn from(value: LocalBootstrapInfo) -> Self {
let LocalBootstrapInfo::V0(info) = value;
let name = info.bootstrap.get_domain();
let url = info.registration_url.clone();
Invitation::V0(InvitationV0 {
bootstrap: info.bootstrap,
code: None,
name,
url,
})
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum InvitationCode {
Unique(SymKey),
@ -609,7 +655,7 @@ impl InvitationV0 {
}
pub fn empty(name: Option<String>) -> Self {
InvitationV0 {
bootstrap: BootstrapContentV0 { servers: vec![] },
bootstrap: BootstrapContentV0::new(),
code: None,
name,
url: None,
@ -668,7 +714,7 @@ impl Invitation {
pub fn intersects(&self, invite2: Invitation) -> Invitation {
let Invitation::V0(v0) = self;
let mut new_invite = InvitationV0 {
bootstrap: BootstrapContentV0 { servers: vec![] },
bootstrap: BootstrapContentV0::new(),
code: v0.code.clone(),
name: v0.name.clone(),
url: v0.url.clone(),
@ -763,18 +809,18 @@ pub enum Invitation {
V0(InvitationV0),
}
impl From<BootstrapContent> for Invitation {
fn from(value: BootstrapContent) -> Self {
let BootstrapContent::V0(boot) = value;
Invitation::V0(InvitationV0 {
bootstrap: boot,
code: None,
name: None,
url: None,
})
}
}
// impl From<BootstrapContent> for Invitation {
// fn from(value: BootstrapContent) -> Self {
// let BootstrapContent::V0(boot) = value;
// let name = boot.get_domain();
// Invitation::V0(InvitationV0 {
// bootstrap: boot,
// code: None,
// name,
// url: None,
// })
// }
// }
/// Create an account at a Broker Service Provider (BSP).
#[derive(Clone, Debug, Serialize, Deserialize)]

@ -115,7 +115,7 @@ pub fn check_is_local_url(bootstrap: &BrokerServerV0, location: &String) -> Opti
}
#[cfg(target_arch = "wasm32")]
async fn retrieve_ng_bootstrap(location: &String) -> Option<BootstrapContent> {
async fn retrieve_ng_bootstrap(location: &String) -> Option<LocalBootstrapInfo> {
let prefix = if (APP_PREFIX == "") {
let url = Url::parse(location).unwrap();
url.origin().unicode_serialization()
@ -126,7 +126,7 @@ async fn retrieve_ng_bootstrap(location: &String) -> Option<BootstrapContent> {
//log_info!("url {}", url);
let resp = reqwest::get(url).await;
if resp.is_ok() {
let resp = resp.unwrap().json::<BootstrapContent>().await;
let resp = resp.unwrap().json::<LocalBootstrapInfo>().await;
return Some(resp.unwrap());
} else {
//log_info!("err {}", resp.unwrap_err());
@ -136,11 +136,11 @@ async fn retrieve_ng_bootstrap(location: &String) -> Option<BootstrapContent> {
#[cfg(target_arch = "wasm32")]
pub async fn retrieve_local_url(location: String) -> Option<String> {
let bootstraps = retrieve_ng_bootstrap(&location).await;
if bootstraps.is_none() {
let info = retrieve_ng_bootstrap(&location).await;
if info.is_none() {
return None;
}
for bootstrap in bootstraps.unwrap().servers() {
for bootstrap in info.unwrap().servers() {
let res = check_is_local_url(bootstrap, &location);
if res.is_some() {
return res;
@ -165,12 +165,11 @@ pub async fn retrieve_local_bootstrap(
log_debug!("invite_String {:?} invite1{:?}", invite_string, invite1);
let invite2: Option<Invitation> = {
let bootstraps = retrieve_ng_bootstrap(&location_string).await;
if bootstraps.is_none() {
let info = retrieve_ng_bootstrap(&location_string).await;
if info.is_none() {
None
} else {
let mut inv: Invitation = bootstraps.unwrap().into();
inv.set_url(BROKER.read().await.get_registration_url());
let mut inv: Invitation = info.unwrap().into();
Some(inv)
}
};

Loading…
Cancel
Save