Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,136 changes: 1,087 additions & 1,049 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions reflection-app/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use adw::prelude::*;
use adw::subclass::prelude::*;
use gettextrs::gettext;
use gtk::{gdk, gio, glib, glib::Properties, glib::clone};
use reflection_doc::{document::DocumentId, identity::PrivateKey, service::Service};
use reflection_doc::{document::DocumentId, identity::SigningKey, service::Service};
use std::{cell::RefCell, fs};
use thiserror::Error;
use tracing::error;
Expand Down Expand Up @@ -258,15 +258,15 @@ impl ReflectionApplication {
}

async fn create_service(&self) -> Result<Service, Error> {
let private_key = secret::get_or_create_identity().await?;
let signing_key = secret::get_or_create_identity().await?;

let mut data_path = glib::user_data_dir();
data_path.push("Reflection");
data_path.push(private_key.public_key().to_string());
data_path.push(signing_key.verifying_key().to_string());
fs::create_dir_all(&data_path)?;
let data_dir = gio::File::for_path(data_path);

let service = Service::new(&private_key, Some(&data_dir));
let service = Service::new(&signing_key, Some(&data_dir));
service.startup().await?;

Ok(service)
Expand Down Expand Up @@ -406,8 +406,8 @@ impl ReflectionApplication {
}

async fn new_temporary_identity(&self) {
let private_key = PrivateKey::new();
let service = Service::new(&private_key, None);
let signing_key = SigningKey::generate();
let service = Service::new(&signing_key, None);

if let Err(error) = service.startup().await {
let error = error.into();
Expand Down
42 changes: 21 additions & 21 deletions reflection-app/src/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use tracing::info;

#[cfg(target_os = "linux")]
use crate::APP_ID;
use reflection_doc::identity::{IdentityError, PrivateKey};
use reflection_doc::identity::{IdentityError, SigningKey};

#[cfg(target_os = "linux")]
const XDG_SCHEMA: &str = "xdg:schema";
Expand Down Expand Up @@ -52,60 +52,60 @@ pub enum Error {
}

#[cfg(target_os = "linux")]
pub async fn get_or_create_identity() -> Result<PrivateKey, Error> {
pub async fn get_or_create_identity() -> Result<SigningKey, Error> {
let keyring = oo7::Keyring::new().await?;

keyring.unlock().await?;

let private_key: PrivateKey =
let signing_key: SigningKey =
if let Some(item) = keyring.search_items(&attributes()).await?.first() {
item.unlock().await?;
let private_key = PrivateKey::try_from(item.secret().await?.as_bytes())?;
info!("Found existing identity: {}", private_key.public_key());
let signing_key = SigningKey::try_from(item.secret().await?.as_bytes())?;
info!("Found existing identity: {}", signing_key.verifying_key());

private_key
signing_key
} else {
let private_key = PrivateKey::new();
let signing_key = SigningKey::generate();
keyring
.create_item("Reflection", &attributes(), private_key.as_bytes(), true)
.create_item("Reflection", &attributes(), signing_key.as_bytes(), true)
.await?;

info!(
"No existing identity found. Create new identity: {}",
private_key.public_key()
signing_key.verifying_key()
);
private_key
signing_key
};

Ok(private_key)
Ok(signing_key)
}

#[cfg(target_os = "macos")]
pub async fn get_or_create_identity() -> Result<PrivateKey, Error> {
pub async fn get_or_create_identity() -> Result<SigningKey, Error> {
let entry = keyring::Entry::new("Reflection Identity", "default user")?;

let private_key: PrivateKey = match entry.get_password() {
let signing_key: SigningKey = match entry.get_password() {
Ok(password) => {
let private_key = PrivateKey::try_from(
let signing_key = SigningKey::try_from(
Base64Engine
.decode(password)
.expect("Failed to decode base64 secret from keyring")
.as_slice(),
)?;
info!("Found existing identity: {}", private_key.public_key());
private_key
info!("Found existing identity: {}", signing_key.verifying_key());
signing_key
}
Err(keyring::Error::NoEntry) => {
let private_key = PrivateKey::new();
entry.set_password(&Base64Engine.encode(private_key.as_bytes()))?;
let signing_key = SigningKey::generate();
entry.set_password(&Base64Engine.encode(signing_key.as_bytes()))?;
info!(
"No existing identity found. Create new identity: {}",
private_key.public_key()
signing_key.verifying_key()
);
private_key
signing_key
}
Err(e) => return Err(Error::Service(e)),
};

Ok(private_key)
Ok(signing_key)
}
3 changes: 2 additions & 1 deletion reflection-doc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ gio = "0.21"
glib = "0.21"
hex = "0.4.3"
indexmap = "2.13.0"
loro = "1.10.8"
loro = "1.12.0"
p2panda-core = "0.6.1"
rand = "0.10.0"
reflection-node = { path = "../reflection-node" }
serde = { version = "1.0.228", features = ["derive"] }
Expand Down
33 changes: 18 additions & 15 deletions reflection-doc/src/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use glib::Properties;
use glib::prelude::*;
use glib::subclass::prelude::*;

use crate::identity::PublicKey;
use crate::identity::VerifyingKey;

pub const COLORS: [(&str, &str); 14] = [
("Yellow", "#faf387"),
Expand Down Expand Up @@ -78,15 +78,15 @@ mod imp {
#[property(name = "emoji", get = Self::emoji, type = String)]
#[property(name = "color", get = Self::color, type = String)]
#[property(name = "hex-color", get = Self::hex_color, type = String)]
#[property(get, set, construct_only, type = PublicKey)]
public_key: OnceLock<PublicKey>,
#[property(get, set, construct_only, type = VerifyingKey)]
verifying_key: OnceLock<VerifyingKey>,
#[property(get, set, construct_only)]
pub last_seen: Mutex<Option<glib::DateTime>>,
#[property(get, default = true)]
pub is_online: Cell<bool>,
#[property(get)]
pub is_this_device: Cell<bool>,
pub last_cursor_update: Mutex<Option<std::time::SystemTime>>,
pub last_cursor_update: Mutex<Option<u64>>,
}

#[glib::object_subclass]
Expand All @@ -100,7 +100,7 @@ mod imp {

impl Author {
fn name(&self) -> String {
let bytes = self.public_key.get().unwrap().as_bytes();
let bytes = self.verifying_key.get().unwrap().as_bytes();
let selector_color = bytes[..(bytes.len() / 2)]
.iter()
.fold(0u8, |acc, b| acc ^ b) as usize
Expand All @@ -113,7 +113,7 @@ mod imp {
}

fn emoji(&self) -> String {
let bytes = self.public_key.get().unwrap().as_bytes();
let bytes = self.verifying_key.get().unwrap().as_bytes();
let selector_emoji = bytes[(bytes.len() / 2)..]
.iter()
.fold(0u8, |acc, b| acc ^ b) as usize
Expand All @@ -122,7 +122,7 @@ mod imp {
}

fn color(&self) -> String {
let bytes = self.public_key.get().unwrap().as_bytes();
let bytes = self.verifying_key.get().unwrap().as_bytes();
let selector_color = bytes[..(bytes.len() / 2)]
.iter()
.fold(0u8, |acc, b| acc ^ b) as usize
Expand All @@ -131,7 +131,7 @@ mod imp {
}

fn hex_color(&self) -> String {
let bytes = self.public_key.get().unwrap().as_bytes();
let bytes = self.verifying_key.get().unwrap().as_bytes();
let selector_color = bytes[..(bytes.len() / 2)]
.iter()
.fold(0u8, |acc, b| acc ^ b) as usize
Expand All @@ -145,24 +145,27 @@ glib::wrapper! {
pub struct Author(ObjectSubclass<imp::Author>);
}
impl Author {
pub(crate) fn new(public_key: &PublicKey) -> Self {
pub(crate) fn new(verifying_key: &VerifyingKey) -> Self {
glib::Object::builder()
.property("public-key", public_key)
.property("verifying-key", verifying_key)
.build()
}

pub(crate) fn with_state(public_key: &PublicKey, last_seen: Option<&glib::DateTime>) -> Self {
pub(crate) fn with_state(
verifying_key: &VerifyingKey,
last_seen: Option<&glib::DateTime>,
) -> Self {
glib::Object::builder()
.property("public-key", public_key)
.property("verifying-key", verifying_key)
.property("last-seen", last_seen)
.build()
}

pub(crate) fn for_this_device(
public_key: &PublicKey,
verifying_key: &VerifyingKey,
last_seen: Option<&glib::DateTime>,
) -> Self {
let obj = Self::with_state(public_key, last_seen);
let obj = Self::with_state(verifying_key, last_seen);

obj.imp().is_this_device.set(true);
obj
Expand All @@ -178,7 +181,7 @@ impl Author {
self.notify_is_online();
}

pub(crate) fn is_new_cursor_position(&self, timestamp: std::time::SystemTime) -> bool {
pub(crate) fn is_new_cursor_position(&self, timestamp: u64) -> bool {
let mut last_cursor_update = self.imp().last_cursor_update.lock().unwrap();

if last_cursor_update.is_none() || timestamp >= last_cursor_update.unwrap() {
Expand Down
16 changes: 8 additions & 8 deletions reflection-doc/src/authors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ use glib::subclass::prelude::*;
use indexmap::IndexMap;

use crate::author::Author;
use crate::identity::PublicKey;
use crate::identity::VerifyingKey;

mod imp {
use super::*;

#[derive(Default)]
pub struct Authors {
pub(super) list: RwLock<IndexMap<PublicKey, Author>>,
pub(super) list: RwLock<IndexMap<VerifyingKey, Author>>,
}

#[glib::object_subclass]
Expand Down Expand Up @@ -70,17 +70,17 @@ impl Authors {
assert_eq!(list.len(), 1);

for author in authors {
let public_key = author.public_key();
if !list.contains_key(&public_key) {
list.insert(public_key, author);
let verifying_key = author.verifying_key();
if !list.contains_key(&verifying_key) {
list.insert(verifying_key, author);
}
}

drop(list);
self.items_changed(1, 0, authors_len as u32);
}

pub(crate) fn add_this_device(&self, author_key: PublicKey) {
pub(crate) fn add_this_device(&self, author_key: VerifyingKey) {
let mut list = self.imp().list.write().unwrap();
let now = glib::DateTime::now_utc().ok();

Expand All @@ -92,7 +92,7 @@ impl Authors {
self.items_changed(0, 0, 1);
}

pub(crate) fn add(&self, author_key: PublicKey) -> Author {
pub(crate) fn add(&self, author_key: VerifyingKey) -> Author {
let mut list = self.imp().list.write().unwrap();
let entry = list.entry(author_key);
let index = entry.index();
Expand All @@ -108,7 +108,7 @@ impl Authors {
author
}

pub(crate) fn author(&self, author_key: &PublicKey) -> Option<Author> {
pub(crate) fn author(&self, author_key: &VerifyingKey) -> Option<Author> {
let list = self.imp().list.read().unwrap();
list.get(author_key).cloned()
}
Expand Down
Loading
Loading