Implemented feature:
- NIP-42 Can be enabled in nix module or as environment variable 'CONFIG_ENABLE_AUTH' - NIP-05 Still WIP, but building up slowly
This commit is contained in:
parent
377da44eed
commit
f7b74bd22c
18 changed files with 1001 additions and 294 deletions
|
@ -1,9 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::usernames::validators::validate_pubkey;
|
||||
use crate::usernames::validators::{validate_pubkey, validate_relays};
|
||||
use crate::utils::error::Error;
|
||||
use nostr::key::XOnlyPublicKey;
|
||||
use nostr::prelude::*;
|
||||
use nostr::{key::XOnlyPublicKey, Keys};
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
@ -12,27 +10,22 @@ lazy_static! {
|
|||
static ref VALID_CHARACTERS: Regex = Regex::new(r"^[a-zA-Z0-9\_]+$").unwrap();
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Validate)]
|
||||
#[derive(Serialize, Deserialize, Debug, Validate, PartialEq, Clone)]
|
||||
pub struct UserBody {
|
||||
#[validate(length(min = 1), regex = "VALID_CHARACTERS")]
|
||||
pub name: String,
|
||||
#[validate(custom(function = "validate_pubkey"))]
|
||||
pub pubkey: String,
|
||||
pubkey: String,
|
||||
#[validate(custom(function = "validate_relays"))]
|
||||
pub relays: Vec<String>
|
||||
}
|
||||
|
||||
impl UserBody {
|
||||
pub fn get_pubkey(&self) -> XOnlyPublicKey {
|
||||
let keys = Keys::from_pk_str(&self.pubkey).unwrap();
|
||||
|
||||
keys.public_key()
|
||||
pub fn get_pubkey(&self) -> String {
|
||||
nostr::Keys::from_pk_str(&self.pubkey).unwrap().public_key().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Nip05 {
|
||||
names: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Validate, Clone)]
|
||||
pub struct UserQuery {
|
||||
#[validate(length(min = 1))]
|
||||
|
|
|
@ -2,10 +2,6 @@ use crate::utils::error::Error;
|
|||
use validator::Validate;
|
||||
use warp::{Filter, Rejection};
|
||||
|
||||
pub fn with_client_ip() {}
|
||||
|
||||
pub fn with_user_body() {}
|
||||
|
||||
pub fn validate_body_filter<T: serde::de::DeserializeOwned + Send + Validate + 'static>(
|
||||
) -> impl Filter<Extract = (T,), Error = Rejection> + Copy {
|
||||
warp::body::json::<T>().and_then(|query: T| async move {
|
||||
|
|
|
@ -6,6 +6,8 @@ use crate::utils::structs::Context;
|
|||
use serde_json::json;
|
||||
use warp::{Rejection, Reply};
|
||||
|
||||
use super::dto::UserBody;
|
||||
|
||||
pub async fn get_account(
|
||||
// account: Result<AccountPubkey, Error>,
|
||||
account: Account,
|
||||
|
@ -47,7 +49,7 @@ pub async fn get_account(
|
|||
pub async fn get_user(user_query: UserQuery, context: Context) -> Result<impl Reply, Rejection> {
|
||||
let mut subscriber = context.pubsub.subscribe(channels::MSG_NIP05).await;
|
||||
|
||||
let command = Command::DbReqGetUser(user_query.name);
|
||||
let command = Command::DbReqGetNIP05(user_query.name);
|
||||
context
|
||||
.pubsub
|
||||
.publish(
|
||||
|
@ -61,7 +63,7 @@ pub async fn get_user(user_query: UserQuery, context: Context) -> Result<impl Re
|
|||
|
||||
if let Ok(message) = subscriber.recv().await {
|
||||
match message.content {
|
||||
Command::DbResUser(profile) => {
|
||||
Command::DbResNIP05(profile) => {
|
||||
let response = serde_json::to_value(profile).unwrap();
|
||||
Ok(warp::reply::json(&response))
|
||||
}
|
||||
|
@ -76,3 +78,35 @@ pub async fn get_user(user_query: UserQuery, context: Context) -> Result<impl Re
|
|||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create_user(user_body: UserBody, context: Context) -> Result<impl Reply, Rejection> {
|
||||
let mut subscriber = context.pubsub.subscribe(channels::MSG_NIP05).await;
|
||||
|
||||
let command = Command::DbReqCreateNIP05(user_body);
|
||||
context
|
||||
.pubsub
|
||||
.publish(
|
||||
channels::MSG_NOOSE,
|
||||
Message {
|
||||
source: channels::MSG_NIP05,
|
||||
content: command,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
if let Ok(message) = subscriber.recv().await {
|
||||
match message.content {
|
||||
Command::DbResOk => {
|
||||
Ok(warp::http::StatusCode::CREATED)
|
||||
}
|
||||
Command::ServiceError(e) => Err(warp::reject::custom(e)),
|
||||
_ => Err(warp::reject::custom(Error::internal_with_message(
|
||||
"Unhandeled message type",
|
||||
))),
|
||||
}
|
||||
} else {
|
||||
Err(warp::reject::custom(Error::internal_with_message(
|
||||
"Unhandeled message type",
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::noose::user::User;
|
||||
|
||||
// use super::accounts::create_account;
|
||||
use super::dto::{Account, UserQuery};
|
||||
use super::dto::{Account, UserBody, UserQuery};
|
||||
use super::filter::{validate_body_filter, validate_query_filter};
|
||||
use super::handler::{get_account, get_user};
|
||||
use super::handler::{create_user, get_account, get_user};
|
||||
use crate::utils::filter::with_context;
|
||||
use crate::utils::structs::Context;
|
||||
use warp::{Filter, Rejection, Reply};
|
||||
|
@ -14,25 +14,37 @@ pub fn routes(context: Context) -> impl Filter<Extract = impl Reply, Error = Rej
|
|||
|
||||
index
|
||||
.or(nip05_get(context.clone()))
|
||||
// .or(account_create(context.clone()))
|
||||
.or(nip05_create(context.clone()))
|
||||
.with(&cors)
|
||||
}
|
||||
|
||||
fn well_known() -> impl Filter<Extract = (), Error = Rejection> + Clone {
|
||||
warp::get().and(warp::path(".well-known"))
|
||||
fn well_known<M>(warp_method: M) -> impl Filter<Extract = (), Error = Rejection> + Clone
|
||||
where
|
||||
M: (Filter<Extract = (), Error = Rejection>) + Copy,
|
||||
{
|
||||
warp_method.and(warp::path(".well-known"))
|
||||
}
|
||||
|
||||
fn nostr_well_known() -> impl Filter<Extract = (), Error = Rejection> + Clone {
|
||||
well_known().and(warp::path("nostr.json"))
|
||||
well_known(warp::get()).and(warp::path("nostr.json"))
|
||||
}
|
||||
|
||||
pub fn nip05_get(context: Context) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
fn nip05_get(context: Context) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
nostr_well_known()
|
||||
.and(validate_query_filter::<UserQuery>())
|
||||
.and(with_context(context.clone()))
|
||||
.and_then(get_user)
|
||||
}
|
||||
|
||||
fn nip05_create(context: Context) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
well_known(warp::post())
|
||||
.and(warp::path("nostr.json"))
|
||||
.and(warp::body::content_length_limit(1024))
|
||||
.and(validate_body_filter::<UserBody>())
|
||||
.and(with_context(context.clone()))
|
||||
.and_then(create_user)
|
||||
}
|
||||
|
||||
// pub fn account_create(
|
||||
// context: Context,
|
||||
// ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::dto::AccountPubkey;
|
||||
use crate::utils::error::Error;
|
||||
use nostr::prelude::FromPkStr;
|
||||
use validator::{Validate, ValidationError};
|
||||
use validator::{Validate, ValidationError, validate_url};
|
||||
|
||||
pub async fn validate_account_pubkey_query(
|
||||
account_pubkey: AccountPubkey,
|
||||
|
@ -25,6 +25,18 @@ pub fn validate_pubkey(value: &str) -> Result<(), ValidationError> {
|
|||
|
||||
match nostr::Keys::from_pk_str(value) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(ValidationError::new("Unable to parse pk_str")),
|
||||
Err(_) => Err(ValidationError::new("Failed to parse pubkey")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn validate_relays(relays: &Vec<String>) -> Result<(), ValidationError> {
|
||||
if relays.is_empty() {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
if relays.iter().all(validate_url) {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
Err(ValidationError::new("Relays have wrong url format"))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue