this_me/
me.rs

1//this.me/crate/src/me.rs
2//by suiGn
3use crate::utils::validate_input::validate_alias;
4use crate::utils::validate_input::validate_hash;
5use rusqlite::Connection;
6use crate::db::connect;
7use serde::Serialize;
8use crate::verbs::Verbs;
9use ed25519_dalek::{SigningKey, SecretKey, VerifyingKey};
10use rand::rngs::OsRng;
11use rand::RngCore;
12use base64::engine::general_purpose::STANDARD;
13use base64::Engine as _;
14use crate::utils::crypto::{encrypt_string, decrypt_string};
15use std::convert::TryFrom;  // Added this line
16/// Represents a local encrypted identity used in dApps or Web3 environments.
17#[derive(Serialize)]
18pub struct Me {
19    pub alias: String,
20    pub public_key: String,
21    pub private_key: String, // stored encrypted
22    pub verbs: Verbs,
23    #[serde(skip)]
24    pub conn: Connection,
25}
26
27impl Me {
28    /// Returns a pretty-printed JSON representation of the Me struct.
29    pub fn display(&self) -> Result<String, MeError> {
30        serde_json::to_string_pretty(self).map_err(|e| MeError::Serialization(e))
31    }
32
33/// Initializes a new Me instance with the given alias and hash.
34pub fn new(alias: &str, _hash: &str) -> Result<(Self, bool), MeError> {
35    validate_alias(alias).map_err(|e| MeError::Validation(e.to_string()))?;
36    validate_hash(_hash).map_err(|e| MeError::Validation(e.to_string()))?;
37    let home = dirs::home_dir().ok_or_else(|| MeError::Validation("No HOME dir".to_string()))?;
38    let db_path = home.join(".this").join("me").join(alias).join(format!("{}.db", alias));
39    if db_path.exists() {
40        return Err(MeError::Validation("Identity already exists.".to_string()));
41    }
42
43    let (conn, _) = connect(alias, true).map_err(MeError::Database)?;
44
45    let mut csprng = OsRng {};
46    let mut secret_bytes = [0u8; 32];
47    csprng.fill_bytes(&mut secret_bytes);
48    let secret = SecretKey::try_from(&secret_bytes[..])
49        .map_err(|_| MeError::Crypto("Invalid secret key".into()))?;
50    let signing_key = SigningKey::from(&secret);
51    let verify_key = VerifyingKey::from(&signing_key);
52    let public_key = STANDARD.encode(verify_key.to_bytes());
53    let private_key_raw = STANDARD.encode(signing_key.to_bytes());
54    let encrypted_private_key = encrypt_string(_hash, &private_key_raw).map_err(|_| MeError::Crypto("Encryption failed".into()))?;
55
56    conn.execute(
57        "CREATE TABLE IF NOT EXISTS identity_keys (public_key TEXT NOT NULL, private_key BLOB NOT NULL)",
58        [],
59    ).map_err(MeError::Database)?;
60
61    conn.execute(
62        "INSERT INTO identity_keys (public_key, private_key) VALUES (?1, ?2)",
63        (&public_key, &encrypted_private_key),
64    ).map_err(MeError::Database)?;
65
66    Ok((Me {
67        alias: alias.to_string(),
68        public_key,
69        private_key: private_key_raw,
70        verbs: Verbs::new(),
71        conn,
72    }, false))
73}
74
75    pub fn be(&mut self, key: &str, value: &str) -> Result<(), MeError> {
76        Ok(self.verbs.be(&self.conn, key, value)?)}
77    pub fn do_(&mut self, key: &str, value: &str) -> Result<(), MeError> {
78        Ok(self.verbs.do_(&self.conn, key, value)?)}
79    pub fn have(&mut self, key: &str, value: &str) -> Result<(), MeError> {
80        Ok(self.verbs.have(&self.conn, key, value)?)}
81    pub fn at(&mut self, key: &str, value: &str) -> Result<(), MeError> {
82        Ok(self.verbs.at(&self.conn, key, value)?)}
83    pub fn relate(&mut self, key: &str, value: &str) -> Result<(), MeError> {
84        Ok(self.verbs.relate(&self.conn, key, value)?) }
85    pub fn react(&mut self, key: &str, value: &str) -> Result<(), MeError> {
86        Ok(self.verbs.react(&self.conn, key, value)?) }
87    pub fn communication(&mut self, key: &str, value: &str) -> Result<(), MeError> {
88        Ok(self.verbs.communication(&self.conn, key, value)?)
89    }
90
91    /// Loads an existing identity by validating and preparing the instance.
92    pub fn load(alias: &str, _hash: &str) -> Result<Self, MeError> {
93        validate_alias(alias).map_err(|e| MeError::Validation(e.to_string()))?;
94        let home = dirs::home_dir().ok_or_else(|| MeError::Validation("No HOME dir".to_string()))?;
95        let db_path = home.join(".this").join("me").join(alias).join(format!("{}.db", alias));
96        let conn = rusqlite::Connection::open(db_path).map_err(MeError::Database)?;
97        let (public_key, private_key_encrypted): (String, Vec<u8>) = {
98            let mut stmt = conn.prepare("SELECT public_key, private_key FROM identity_keys LIMIT 1")
99                .map_err(MeError::Database)?;
100
101            stmt.query_row([], |row| {
102                Ok((row.get(0)?, row.get(1)?))
103            }).map_err(MeError::Database)?
104        };
105
106        let private_key = decrypt_string(_hash, &private_key_encrypted)
107            .map_err(|_| MeError::Crypto("Decryption failed".into()))?;
108
109        Ok(Me {
110            alias: alias.to_string(),
111            public_key,
112            private_key,
113            verbs: Verbs::new(),
114            conn,
115        })
116    }
117}
118
119pub use crate::utils::me_error::MeError;