mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-11-26 23:27:14 +03:00
register: verify username and signature upon boot
This commit is contained in:
parent
57f7978dca
commit
01f2721e50
@ -31,6 +31,9 @@ alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" }
|
|||||||
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4", features = ["ws"]}
|
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4", features = ["ws"]}
|
||||||
alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" }
|
alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" }
|
||||||
alloy-providers = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" }
|
alloy-providers = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" }
|
||||||
|
alloy-primitives = "0.6.2"
|
||||||
|
alloy-sol-macro = "0.6.2"
|
||||||
|
alloy-sol-types = "0.6.2"
|
||||||
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" }
|
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" }
|
||||||
anyhow = "1.0.71"
|
anyhow = "1.0.71"
|
||||||
async-trait = "0.1.71"
|
async-trait = "0.1.71"
|
||||||
@ -86,3 +89,4 @@ warp = "0.3.5"
|
|||||||
wasmtime = "17.0.1"
|
wasmtime = "17.0.1"
|
||||||
wasmtime-wasi = "17.0.1"
|
wasmtime-wasi = "17.0.1"
|
||||||
zip = "0.6"
|
zip = "0.6"
|
||||||
|
tiny-keccak = "1.4.2"
|
@ -10,6 +10,7 @@ use ring::rand::SystemRandom;
|
|||||||
use ring::signature::{self, KeyPair};
|
use ring::signature::{self, KeyPair};
|
||||||
use ring::{digest as ring_digest, rand::SecureRandom};
|
use ring::{digest as ring_digest, rand::SecureRandom};
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
use tiny_keccak::Keccak;
|
||||||
|
|
||||||
use lib::types::core::Keyfile;
|
use lib::types::core::Keyfile;
|
||||||
|
|
||||||
@ -107,6 +108,24 @@ pub fn get_username_and_routers(keyfile: &[u8]) -> Result<(String, Vec<String>),
|
|||||||
Ok((username, routers))
|
Ok((username, routers))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn namehash(name: &str) -> Vec<u8> {
|
||||||
|
let mut node = vec![0u8; 32];
|
||||||
|
if name.is_empty() {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
let mut labels: Vec<&str> = name.split(".").collect();
|
||||||
|
labels.reverse();
|
||||||
|
for label in labels.iter() {
|
||||||
|
let mut labelhash = [0u8; 32];
|
||||||
|
Keccak::keccak256(label.as_bytes(), &mut labelhash);
|
||||||
|
node.append(&mut labelhash.to_vec());
|
||||||
|
labelhash = [0u8; 32];
|
||||||
|
Keccak::keccak256(node.as_slice(), &mut labelhash);
|
||||||
|
node = labelhash.to_vec();
|
||||||
|
}
|
||||||
|
node
|
||||||
|
}
|
||||||
|
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// a pair of (public key (encoded as a hex string), serialized key as a pkcs8 Document)
|
/// a pair of (public key (encoded as a hex string), serialized key as a pkcs8 Document)
|
||||||
pub fn generate_networking_key() -> (String, Document) {
|
pub fn generate_networking_key() -> (String, Document) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.054f6f32.css",
|
"main.css": "/static/css/main.054f6f32.css",
|
||||||
"main.js": "/static/js/main.431aef9a.js",
|
"main.js": "/static/js/main.75ba0410.js",
|
||||||
"static/media/unknown.png": "/static/media/unknown.880d04d4611a45ab1001.png",
|
"static/media/unknown.png": "/static/media/unknown.880d04d4611a45ab1001.png",
|
||||||
"static/media/background.jpg": "/static/media/background.01d2427cfc21fb685016.jpg",
|
"static/media/background.jpg": "/static/media/background.01d2427cfc21fb685016.jpg",
|
||||||
"static/media/kinode.svg": "/static/media/kinode.86d0c1a6a4a3ca3be41616b5989d6925.svg",
|
"static/media/kinode.svg": "/static/media/kinode.86d0c1a6a4a3ca3be41616b5989d6925.svg",
|
||||||
@ -10,6 +10,6 @@
|
|||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.054f6f32.css",
|
"static/css/main.054f6f32.css",
|
||||||
"static/js/main.431aef9a.js"
|
"static/js/main.75ba0410.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><title>Welcome - Kinode</title><meta charset="utf-8"/><meta http-equiv="pragma" content="no-cache"/><meta http-equiv="cache-control" content="no-cache"/><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet"><link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzc5IiBoZWlnaHQ9IjUxNCIgdmlld0JveD0iMCAwIDc3OSA1MTQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8c3R5bGU+CiAgICAgICAgQG1lZGlhIChwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykgewogICAgICAgICAgICBzdmcgeyBmaWxsOiB3aGl0ZTsgfQogICAgICAgIH0KICAgICAgICBAbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkgewogICAgICAgICAgICBzdmcgeyBmaWxsOiBibGFjazsgfQogICAgICAgIH0KICAgIDwvc3R5bGU+CiAgICA8cGF0aCBkPSJNNzUzLjA5MiA1LjkxOTMyQzc1Ni41NTcgNS4wOTk3NiA3NTUuOTYyIC0wLjAwMDEyMjA3IDc1Mi40MDEgLTAuMDAwMTIyMDdINDI2LjAwMUM0MjQuNzU1IC0wLjAwMDEyMjA3IDQyMy42MzkgMC43NzAyNyA0MjMuMTk3IDEuOTM1MzVMMjM2Ljk2OCA0OTIuNkMyMzUuNzI5IDQ5NS44NjUgMjQwLjEyMyA0OTguMjU1IDI0Mi4xOTEgNDk1LjQ0MUw1NjkuMzU3IDUwLjExMzJDNTY5Ljc3OCA0OS41MzkyIDU3MC4zOTEgNDkuMTMzOSA1NzEuMDg0IDQ4Ljk3TDc1My4wOTIgNS45MTkzMloiLz4KICAgIDxwYXRoIGQ9Ik0xMS45NjY1IDQwLjIyODhDOS4xMDk0OSAzOC43NzcgMTAuMjEzNSAzNC40NTgzIDEzLjQxNjcgMzQuNTU1N0w0MDQuMjczIDQ2LjQzNjdDNDA2LjMzNCA0Ni40OTkzIDQwNy43MTkgNDguNTc0OSA0MDYuOTg2IDUwLjUwMjNMMzQ3LjQzOCAyMDYuOTgxQzM0Ni44MDQgMjA4LjY0NyAzNDQuODY1IDIwOS4zOTYgMzQzLjI3NSAyMDguNTg4TDExLjk2NjUgNDAuMjI4OFoiLz4KPC9zdmc+Cg=="><meta httpequiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"/><script defer="defer" src="/static/js/main.431aef9a.js"></script><link href="/static/css/main.054f6f32.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
<!doctype html><html lang="en"><head><title>Welcome - Kinode</title><meta charset="utf-8"/><meta http-equiv="pragma" content="no-cache"/><meta http-equiv="cache-control" content="no-cache"/><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet"><link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzc5IiBoZWlnaHQ9IjUxNCIgdmlld0JveD0iMCAwIDc3OSA1MTQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8c3R5bGU+CiAgICAgICAgQG1lZGlhIChwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykgewogICAgICAgICAgICBzdmcgeyBmaWxsOiB3aGl0ZTsgfQogICAgICAgIH0KICAgICAgICBAbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkgewogICAgICAgICAgICBzdmcgeyBmaWxsOiBibGFjazsgfQogICAgICAgIH0KICAgIDwvc3R5bGU+CiAgICA8cGF0aCBkPSJNNzUzLjA5MiA1LjkxOTMyQzc1Ni41NTcgNS4wOTk3NiA3NTUuOTYyIC0wLjAwMDEyMjA3IDc1Mi40MDEgLTAuMDAwMTIyMDdINDI2LjAwMUM0MjQuNzU1IC0wLjAwMDEyMjA3IDQyMy42MzkgMC43NzAyNyA0MjMuMTk3IDEuOTM1MzVMMjM2Ljk2OCA0OTIuNkMyMzUuNzI5IDQ5NS44NjUgMjQwLjEyMyA0OTguMjU1IDI0Mi4xOTEgNDk1LjQ0MUw1NjkuMzU3IDUwLjExMzJDNTY5Ljc3OCA0OS41MzkyIDU3MC4zOTEgNDkuMTMzOSA1NzEuMDg0IDQ4Ljk3TDc1My4wOTIgNS45MTkzMloiLz4KICAgIDxwYXRoIGQ9Ik0xMS45NjY1IDQwLjIyODhDOS4xMDk0OSAzOC43NzcgMTAuMjEzNSAzNC40NTgzIDEzLjQxNjcgMzQuNTU1N0w0MDQuMjczIDQ2LjQzNjdDNDA2LjMzNCA0Ni40OTkzIDQwNy43MTkgNDguNTc0OSA0MDYuOTg2IDUwLjUwMjNMMzQ3LjQzOCAyMDYuOTgxQzM0Ni44MDQgMjA4LjY0NyAzNDQuODY1IDIwOS4zOTYgMzQzLjI3NSAyMDguNTg4TDExLjk2NjUgNDAuMjI4OFoiLz4KPC9zdmc+Cg=="><meta httpequiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"/><script defer="defer" src="/static/js/main.75ba0410.js"></script><link href="/static/css/main.054f6f32.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
File diff suppressed because one or more lines are too long
@ -1,12 +1,22 @@
|
|||||||
use aes_gcm::aead::KeyInit;
|
use aes_gcm::aead::KeyInit;
|
||||||
|
use alloy_primitives::{Address, Bytes, FixedBytes, U256};
|
||||||
|
use alloy_providers::provider::{Provider, TempProvider};
|
||||||
|
use alloy_pubsub::PubSubFrontend;
|
||||||
|
use alloy_rpc_client::ClientBuilder;
|
||||||
|
use alloy_rpc_types::request::{TransactionInput, TransactionRequest};
|
||||||
use alloy_signer::Signature;
|
use alloy_signer::Signature;
|
||||||
|
use alloy_sol_macro::sol;
|
||||||
|
use alloy_sol_types::{SolCall, SolValue};
|
||||||
|
use alloy_transport_ws::WsConnect;
|
||||||
use hmac::Hmac;
|
use hmac::Hmac;
|
||||||
use jwt::{FromBase64, SignWithKey};
|
use jwt::SignWithKey;
|
||||||
use ring::rand::SystemRandom;
|
use ring::rand::SystemRandom;
|
||||||
use ring::signature;
|
use ring::signature;
|
||||||
use ring::signature::KeyPair;
|
use ring::signature::KeyPair;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
use static_dir::static_dir;
|
use static_dir::static_dir;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
@ -23,8 +33,24 @@ use lib::types::core::*;
|
|||||||
|
|
||||||
type RegistrationSender = mpsc::Sender<(Identity, Keyfile, Vec<u8>)>;
|
type RegistrationSender = mpsc::Sender<(Identity, Keyfile, Vec<u8>)>;
|
||||||
|
|
||||||
pub const KNS_SEPOLIA_ADDRESS: &str = "0x3807fBD692Aa5c96F1D8D7c59a1346a885F40B1C";
|
pub const KNS_SEPOLIA_ADDRESS: Address = Address::new([
|
||||||
pub const KNS_OPTIMISM_ADDRESS: &str = "0xca5b5811c0C40aAB3295f932b1B5112Eb7bb4bD6";
|
0x38, 0x07, 0xFB, 0xD6, 0x92, 0xAa, 0x5c, 0x96, 0xF1, 0xD8, 0xD7, 0xc5, 0x9a, 0x13, 0x46, 0xa8,
|
||||||
|
0x85, 0xF4, 0x0B, 0x1C,
|
||||||
|
]);
|
||||||
|
|
||||||
|
pub const KNS_OPTIMISM_ADDRESS: Address = Address::new([
|
||||||
|
0xca, 0x5b, 0x58, 0x11, 0xc0, 0xC4, 0x0a, 0xAB, 0x32, 0x95, 0xf9, 0x32, 0xb1, 0xB5, 0x11, 0x2E,
|
||||||
|
0xb7, 0xbb, 0x4b, 0xD6,
|
||||||
|
]);
|
||||||
|
|
||||||
|
sol! {
|
||||||
|
function auth(
|
||||||
|
bytes32 _node,
|
||||||
|
address _sender
|
||||||
|
) public view virtual returns (bool authed);
|
||||||
|
|
||||||
|
function nodes(bytes32) external view returns (address, uint96);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _ip_to_number(ip: &str) -> Result<u32, &'static str> {
|
pub fn _ip_to_number(ip: &str) -> Result<u32, &'static str> {
|
||||||
let octets: Vec<&str> = ip.split('.').collect();
|
let octets: Vec<&str> = ip.split('.').collect();
|
||||||
@ -120,6 +146,24 @@ pub async fn register(
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// KnsRegistrar contract address
|
||||||
|
let kns_address = if testnet {
|
||||||
|
KNS_SEPOLIA_ADDRESS
|
||||||
|
} else {
|
||||||
|
KNS_OPTIMISM_ADDRESS
|
||||||
|
};
|
||||||
|
|
||||||
|
// This ETH provider uses public rpc endpoints to verify registration signatures.
|
||||||
|
let url = if testnet {
|
||||||
|
"wss://ethereum-sepolia-rpc.publicnode.com".to_string()
|
||||||
|
} else {
|
||||||
|
"wss://optimism-rpc.publicnode.com".to_string()
|
||||||
|
};
|
||||||
|
let connector = WsConnect { url, auth: None };
|
||||||
|
let client = ClientBuilder::default().ws(connector).await.unwrap();
|
||||||
|
|
||||||
|
let provider = Arc::new(Provider::new_with_client(client));
|
||||||
|
|
||||||
let keyfile = warp::any().map(move || keyfile.clone());
|
let keyfile = warp::any().map(move || keyfile.clone());
|
||||||
let our_temp_id = warp::any().map(move || our_temp_id.clone());
|
let our_temp_id = warp::any().map(move || our_temp_id.clone());
|
||||||
let net_keypair = warp::any().map(move || net_keypair.clone());
|
let net_keypair = warp::any().map(move || net_keypair.clone());
|
||||||
@ -182,7 +226,18 @@ pub async fn register(
|
|||||||
.and(tx.clone())
|
.and(tx.clone())
|
||||||
.and(our_temp_id.clone())
|
.and(our_temp_id.clone())
|
||||||
.and(net_keypair.clone())
|
.and(net_keypair.clone())
|
||||||
.and_then(handle_boot),
|
.and_then(move |boot_info, tx, our_temp_id, net_keypair| {
|
||||||
|
let provider = provider.clone();
|
||||||
|
handle_boot(
|
||||||
|
boot_info,
|
||||||
|
tx,
|
||||||
|
our_temp_id,
|
||||||
|
net_keypair,
|
||||||
|
testnet,
|
||||||
|
kns_address,
|
||||||
|
provider,
|
||||||
|
)
|
||||||
|
}),
|
||||||
))
|
))
|
||||||
.or(warp::path("import-keyfile").and(
|
.or(warp::path("import-keyfile").and(
|
||||||
warp::post()
|
warp::post()
|
||||||
@ -254,14 +309,6 @@ async fn get_unencrypted_info(keyfile: Option<Vec<u8>>) -> Result<impl Reply, Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// do we need password salt here for the FE to hash the login password?
|
|
||||||
println!(
|
|
||||||
"unencrypted info return: {:?}",
|
|
||||||
UnencryptedIdentity {
|
|
||||||
name: name.clone(),
|
|
||||||
allowed_routers: allowed_routers.clone(),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return Ok(warp::reply::with_status(
|
return Ok(warp::reply::with_status(
|
||||||
warp::reply::json(&UnencryptedIdentity {
|
warp::reply::json(&UnencryptedIdentity {
|
||||||
name,
|
name,
|
||||||
@ -273,7 +320,6 @@ async fn get_unencrypted_info(keyfile: Option<Vec<u8>>) -> Result<impl Reply, Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn generate_networking_info(our_temp_id: Arc<Identity>) -> Result<impl Reply, Rejection> {
|
async fn generate_networking_info(our_temp_id: Arc<Identity>) -> Result<impl Reply, Rejection> {
|
||||||
println!("temp ID {:?}", our_temp_id.as_ref());
|
|
||||||
Ok(warp::reply::json(our_temp_id.as_ref()))
|
Ok(warp::reply::json(our_temp_id.as_ref()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,10 +352,11 @@ async fn handle_boot(
|
|||||||
sender: Arc<RegistrationSender>,
|
sender: Arc<RegistrationSender>,
|
||||||
our: Arc<Identity>,
|
our: Arc<Identity>,
|
||||||
networking_keypair: Arc<Vec<u8>>,
|
networking_keypair: Arc<Vec<u8>>,
|
||||||
|
testnet: bool,
|
||||||
|
kns_address: Address,
|
||||||
|
provider: Arc<Provider<PubSubFrontend>>,
|
||||||
) -> Result<impl Reply, Rejection> {
|
) -> Result<impl Reply, Rejection> {
|
||||||
let mut our = our.as_ref().clone();
|
let mut our = our.as_ref().clone();
|
||||||
println!("bootinfo while booting: {:?}", info.clone());
|
|
||||||
println!("our while booting: {:?}", our.clone());
|
|
||||||
|
|
||||||
our.name = info.username;
|
our.name = info.username;
|
||||||
if info.direct {
|
if info.direct {
|
||||||
@ -321,33 +368,98 @@ async fn handle_boot(
|
|||||||
let mut jwt_secret = [0u8, 32];
|
let mut jwt_secret = [0u8, 32];
|
||||||
ring::rand::SecureRandom::fill(&jwt_seed, &mut jwt_secret).unwrap();
|
ring::rand::SecureRandom::fill(&jwt_seed, &mut jwt_secret).unwrap();
|
||||||
|
|
||||||
// let salt = base64::decode(&info.salt).map_err(|_| warp::reject())?;
|
// verifying owner + signature, get registrar contract, call auth()
|
||||||
//let sig = Signature::from_base64(&info.signature).map_err(|_| warp::reject())?;
|
|
||||||
|
|
||||||
let now = SystemTime::now()
|
let now = SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.expect("Time went backwards")
|
.expect("Time went backwards")
|
||||||
.as_secs();
|
.as_secs();
|
||||||
|
|
||||||
// if info.timestamp < now + 120 {
|
if info.timestamp < now + 120 {
|
||||||
// return Ok(warp::reply::with_status(
|
return Ok(warp::reply::with_status(
|
||||||
// warp::reply::json(&"Timestamp is outdated."),
|
warp::reply::json(&"Timestamp is outdated."),
|
||||||
// StatusCode::UNAUTHORIZED,
|
StatusCode::UNAUTHORIZED,
|
||||||
// )
|
)
|
||||||
// .into_response());
|
.into_response());
|
||||||
// }
|
}
|
||||||
|
|
||||||
// verify eth signature, fetch from eth?
|
let namehash = FixedBytes::<32>::from_slice(&keygen::namehash(&our.name));
|
||||||
// let sign_data = serde_json::to_vec(&serde_json::json!({
|
let tld_call = nodesCall { _0: namehash }.abi_encode();
|
||||||
// "password": info.password,
|
let tx_input = TransactionInput::new(Bytes::from(tld_call));
|
||||||
// "timestamp": info.timestamp,
|
let tx = TransactionRequest {
|
||||||
// }))
|
to: Some(kns_address),
|
||||||
// .unwrap();
|
input: tx_input,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
// check chain for address match...?
|
let Ok(tld) = provider.call(tx, None).await else {
|
||||||
// let _signer = sig
|
return Ok(warp::reply::with_status(
|
||||||
// .recover_address_from_msg(&sign_data)
|
warp::reply::json(&"Failed to fetch TLD contract for username"),
|
||||||
// .map_err(|_| warp::reject())?;
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
)
|
||||||
|
.into_response());
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok((tld_address, _)) = <(Address, U256)>::abi_decode(&tld, false) else {
|
||||||
|
return Ok(warp::reply::with_status(
|
||||||
|
warp::reply::json(&"Failed to decode TLD contract from return bytes"),
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
)
|
||||||
|
.into_response());
|
||||||
|
};
|
||||||
|
let owner = Address::from_str(&info.owner).map_err(|_| warp::reject())?;
|
||||||
|
|
||||||
|
let auth_call = authCall {
|
||||||
|
_node: namehash,
|
||||||
|
_sender: owner,
|
||||||
|
}
|
||||||
|
.abi_encode();
|
||||||
|
let tx_input = TransactionInput::new(Bytes::from(auth_call));
|
||||||
|
let tx = TransactionRequest {
|
||||||
|
to: Some(tld_address),
|
||||||
|
input: tx_input,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(authed) = provider.call(tx, None).await else {
|
||||||
|
return Ok(warp::reply::with_status(
|
||||||
|
warp::reply::json(&"Failed to fetch TLD contract for username"),
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
)
|
||||||
|
.into_response());
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_ok = bool::abi_decode(&authed, false).map_err(|_| warp::reject())?;
|
||||||
|
|
||||||
|
if !is_ok {
|
||||||
|
return Ok(warp::reply::with_status(
|
||||||
|
warp::reply::json(&"Address is not authorized for username!"),
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
.into_response());
|
||||||
|
};
|
||||||
|
|
||||||
|
// manual json creation to preserve order..
|
||||||
|
let sig_data_json = format!(
|
||||||
|
r#"{{"username":"{}","password":"{}","timestamp":{}}}"#,
|
||||||
|
our.name, info.password, info.timestamp
|
||||||
|
);
|
||||||
|
let sig_data = sig_data_json.as_bytes();
|
||||||
|
|
||||||
|
let sig = Signature::from_str(&info.signature).map_err(|_| warp::reject())?;
|
||||||
|
|
||||||
|
let recovered_address = sig
|
||||||
|
.recover_address_from_msg(sig_data)
|
||||||
|
.map_err(|_| warp::reject())?;
|
||||||
|
|
||||||
|
if recovered_address != owner {
|
||||||
|
return Ok(warp::reply::with_status(
|
||||||
|
warp::reply::json(&"Recovered address does not match owner"),
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
.into_response());
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("success baby.");
|
||||||
|
|
||||||
let decoded_keyfile = Keyfile {
|
let decoded_keyfile = Keyfile {
|
||||||
username: our.name.clone(),
|
username: our.name.clone(),
|
||||||
|
@ -784,8 +784,9 @@ pub struct BootInfo {
|
|||||||
pub username: String,
|
pub username: String,
|
||||||
pub reset: bool,
|
pub reset: bool,
|
||||||
pub direct: bool,
|
pub direct: bool,
|
||||||
// pub signature: String,
|
pub owner: String,
|
||||||
// pub timestamp: u64,
|
pub signature: String,
|
||||||
|
pub timestamp: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
Loading…
Reference in New Issue
Block a user