150 lines
3.7 KiB
Rust
150 lines
3.7 KiB
Rust
use regex::Regex;
|
|
use rusqlite::Row;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
use validator::{Validate, ValidationError};
|
|
|
|
lazy_static! {
|
|
static ref VALID_CHARACTERS: Regex = Regex::new(r"^[a-zA-Z0-9\_]+$").unwrap();
|
|
}
|
|
|
|
pub enum Nip05Table {
|
|
Table,
|
|
Pubkey,
|
|
Username,
|
|
Relays,
|
|
JoinedAt,
|
|
}
|
|
|
|
impl sea_query::Iden for Nip05Table {
|
|
fn unquoted(&self, s: &mut dyn std::fmt::Write) {
|
|
write!(
|
|
s,
|
|
"{}",
|
|
match self {
|
|
Self::Table => "nip05",
|
|
Self::Pubkey => "pubkey",
|
|
Self::Username => "username",
|
|
Self::Relays => "relays",
|
|
Self::JoinedAt => "joined_at",
|
|
}
|
|
)
|
|
.unwrap()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
|
pub struct UserRow {
|
|
pub pubkey: String,
|
|
pub username: String,
|
|
relays: Vec<String>,
|
|
joined_at: i64,
|
|
}
|
|
|
|
impl UserRow {
|
|
pub fn new(pubkey: String, username: String, relays: Vec<String>) -> Self {
|
|
Self {
|
|
pubkey,
|
|
username,
|
|
relays,
|
|
joined_at: nostr::Timestamp::now().as_i64(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&Row<'_>> for UserRow {
|
|
fn from(row: &Row) -> Self {
|
|
let pubkey: String = row.get("pubkey").unwrap();
|
|
let username: String = row.get("username").unwrap();
|
|
let relays_raw: String = row.get("relays").unwrap_or_default();
|
|
let joined_at: i64 = row.get("joined_at").unwrap();
|
|
|
|
let relays: Vec<String> = match serde_json::from_str(&relays_raw) {
|
|
Ok(val) => val,
|
|
Err(_) => vec![],
|
|
};
|
|
|
|
Self {
|
|
pubkey,
|
|
username,
|
|
relays,
|
|
joined_at,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
|
pub struct Nip05Profile {
|
|
names: HashMap<String, String>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
relays: Option<HashMap<String, Vec<String>>>,
|
|
}
|
|
|
|
impl From<UserRow> for Nip05Profile {
|
|
fn from(value: UserRow) -> Self {
|
|
let mut name: HashMap<String, String> = HashMap::new();
|
|
name.insert(value.username, value.pubkey.clone());
|
|
|
|
let relay = match value.relays.is_empty() {
|
|
true => None,
|
|
false => {
|
|
let mut relay: HashMap<String, Vec<String>> = HashMap::new();
|
|
relay.insert(value.pubkey.clone(), value.relays);
|
|
|
|
Some(relay)
|
|
}
|
|
};
|
|
|
|
Self {
|
|
names: name,
|
|
relays: relay,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Validate)]
|
|
pub struct User {
|
|
#[validate(custom = "validate_pubkey")]
|
|
pub pubkey: Option<String>,
|
|
#[validate(length(min = 1), regex = "VALID_CHARACTERS")]
|
|
pub name: Option<String>,
|
|
}
|
|
|
|
pub fn validate_pubkey(value: &str) -> Result<(), ValidationError> {
|
|
use nostr::prelude::FromPkStr;
|
|
match nostr::Keys::from_pk_str(value) {
|
|
Ok(_) => Ok(()),
|
|
Err(_) => Err(ValidationError::new("Unable to parse pubkey")),
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::{Nip05Profile, UserRow};
|
|
|
|
#[test]
|
|
fn make_nip05() {
|
|
let user_row = UserRow::new(
|
|
"npub1m2w0ckmkgj4wtvl8muwjynh56j3qd4nddca4exdg4mdrkepvfnhsmusy54".to_string(),
|
|
"test_user".to_string(),
|
|
vec![],
|
|
);
|
|
|
|
let nip05 = Nip05Profile::from(user_row);
|
|
|
|
dbg!(&nip05);
|
|
dbg!(serde_json::to_string(&nip05).unwrap());
|
|
}
|
|
|
|
#[test]
|
|
fn parse_relay_vec() {
|
|
let relays_raw = "";
|
|
let relays: Vec<String> = match serde_json::from_str(relays_raw) {
|
|
Ok(val) => val,
|
|
Err(_) => vec![],
|
|
};
|
|
|
|
dbg!(relays);
|
|
}
|
|
}
|