Skip to content

Commit

Permalink
Merge branch 'main' into thread_title
Browse files Browse the repository at this point in the history
  • Loading branch information
nanu-c committed May 8, 2023
2 parents 8ccedab + 9935bb0 commit c032e2a
Show file tree
Hide file tree
Showing 10 changed files with 476 additions and 239 deletions.
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

### Fixed

### Changed

## [0.5.2]

### Added

- Set registration for PNI (phone-number identity) which will be fully implemented later. (#164)

### Fixed

- Fix synchronization issue in the `sled` store implementation which could lead to corrupted sessions. (#162)
- Don't reuse websocket when sending unidentified messages. (#165)
- Fix fetching groups v2 metadata. (#164)

### Changed

- `Manager::load_registered` is now an async method (small breaking change, sorry!). (#164)

## [0.5.1]

Note: this release splits the project into multiple crates, to prepare for adding concurrent store implementations.
While this might seem like a breaking change, the API has not been altered and your `Cargo.toml` should now look like:

```toml
[dependencies]
presage = { git = "https://github.com/whisperfish/presage" }
presage-store-sled = { git = "https://github.com/whisperfish/presage" }
```

and then get the store implementation from the store crate instead when importing it like `use presage_store_sled::SledStore;`.

### Added

- Add `Manager::submit_recaptcha_challenge`. (#143)
- Cache profile API responses. (#134)
- Add `is_registered` method to the store trait. (#156)

### Fixed

Expand All @@ -23,6 +59,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Handle message deletion sent by contacts. (#147)
- Split `presage` into multiple crates, before introducing additional store implementations. (#148)
- Messages are now sent, whenever possible (which should be all the time), as [sealed sender](https://signal.org/blog/sealed-sender/). [#159]
- Split project into multiple crates. (#148)

## [0.5.0]

Expand Down Expand Up @@ -51,3 +89,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Encrypt registration data (when store encryption is enabled). (#114)

[0.5.0]: https://github.com/whisperfish/presage/compare/0.4.0...0.5.0
[0.5.1]: https://github.com/whisperfish/presage/compare/0.5.0...0.5.1
[0.5.2]: https://github.com/whisperfish/presage/compare/0.5.1...0.5.2
[Unreleased]: https://github.com/whisperfish/presage/compare/0.5.2...main
36 changes: 16 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,29 @@ Features:

## Instructions

Included in this repository is a CLI very similar (on purpose) to the great [signal-cli](https://github.com/AsamK/signal-cli):
Add the following to your `Cargo.toml`:

```toml
[dependencies]
presage = { git = "https://github.com/whisperfish/presage" }
presage-store-sled = { git = "https://github.com/whisperfish/presage" }
```
# print help section
cargo run --example=cli -- --help
# link as secondary device, a PNG with a QR code to scan should open
cargo run --example=cli -- link-device --device-name presage

# start receiving messages
cargo run --example=cli -- receive
```
and look at the generated Rust documentation of the `Manager` struct to get started.

For usage of the library, a few examples are included under the `examples/` directory, and most features are demonstrated
in [examples/cli.rs](./examples/cli.rs).
## Demo CLI

## Migration notes
Included in this repository is a CLI very similar (on purpose) to the great [signal-cli](https://github.com/AsamK/signal-cli):

### Migrating from `0.5.x` to `0.6.x`
```
# print help section
cargo run -- --help
Apart from the few obvious changes in the API, one of the main differences between both versions is that you will now
require to use two crates as `[dependencies]`, one for the library and one for the store backend, which could look like:
# link as secondary device, a PNG with a QR code to scan should open
cargo run -- link-device --device-name presage
```toml
[dependencies]
presage = { git = "https://github.com/whisperfish/presage" }
presage-store-sled = { git = "https://github.com/whisperfish/presage" }
# start receiving messages
cargo run -- receive
```

and then get the store implementation from the store crate instead when importing it like `use presage_store_sled::SledStore;`.
For using the library, the CLI is a good starting point to learn how the API can be used.
2 changes: 1 addition & 1 deletion presage-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ presage-store-sled = { path = "../presage-store-sled" }
anyhow = "1.0"
base64 = "0.12"
chrono = { version = "0.4", default-features = false, features = ["serde", "clock"] }
clap = { version = "3.0", features = ["derive"] }
clap = { version = ">=4.2.4", features = ["derive"] }
directories = "3.0"
env_logger = "0.7"
futures = "0.3"
Expand Down
63 changes: 41 additions & 22 deletions presage-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ use core::fmt;
use std::convert::TryInto;
use std::path::Path;
use std::path::PathBuf;
use std::time::Duration;
use std::time::UNIX_EPOCH;

use anyhow::{anyhow, bail, Context as _};
use chrono::Local;
use clap::{ArgGroup, Parser, Subcommand};
use directories::ProjectDirs;
use env_logger::Env;
use futures::{channel::oneshot, future, pin_mut, StreamExt};
use futures::StreamExt;
use futures::{channel::oneshot, future, pin_mut};
use log::{debug, error, info};
use notify_rust::Notification;
use presage::libsignal_service::content::Reaction;
Expand All @@ -28,6 +30,8 @@ use presage::{
use presage_store_sled::MigrationConflictStrategy;
use presage_store_sled::SledStore;
use tempfile::Builder;
use tokio::task;
use tokio::time::sleep;
use tokio::{
fs,
io::{self, AsyncBufReadExt, BufReader},
Expand Down Expand Up @@ -198,7 +202,7 @@ async fn main() -> anyhow::Result<()> {
run(args.subcommand, config_store).await
}

async fn send<C: Store>(
async fn send<C: Store + 'static>(
msg: &str,
uuid: &Uuid,
manager: &mut Manager<C, Registered>,
Expand All @@ -214,12 +218,27 @@ async fn send<C: Store>(
..Default::default()
});

let mut m = manager.clone();
let _ = future::join(
receive(&mut m, false),
manager.send_message(*uuid, message, timestamp),
)
.await;
let local = task::LocalSet::new();

local
.run_until(async move {
let mut receiving_manager = manager.clone();
task::spawn_local(async move {
if let Err(e) = receive(&mut receiving_manager, false).await {
error!("error while receiving stuff: {e}");
}
});

sleep(Duration::from_secs(5)).await;

manager
.send_message(*uuid, message, timestamp)
.await
.unwrap();

sleep(Duration::from_secs(5)).await;
})
.await;

Ok(())
}
Expand Down Expand Up @@ -318,7 +337,7 @@ fn print_message<C: Store>(
.ok()
.flatten()
.filter(|c| !c.name.is_empty())
.map(|c| c.name)
.map(|c| format!("{}: {}", c.name, uuid))
.unwrap_or_else(|| uuid.to_string())
};

Expand Down Expand Up @@ -370,7 +389,7 @@ fn print_message<C: Store>(
(format!("To {contact} @ {ts}"), body)
}
Msg::Received(Thread::Group(key), body) => {
let sender = content.metadata.sender.uuid;
let sender = format_contact(&content.metadata.sender.uuid);
let group = format_group(key);
(format!("From {sender} to group {group} @ {ts}: "), body)
}
Expand Down Expand Up @@ -419,7 +438,7 @@ async fn receive<C: Store>(
Ok(())
}

async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
async fn run<C: Store + 'static>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
match subcommand {
Cmd::Register {
servers,
Expand Down Expand Up @@ -481,18 +500,18 @@ async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
}
}
Cmd::Receive { notifications } => {
let mut manager = Manager::load_registered(config_store)?;
let mut manager = Manager::load_registered(config_store).await?;
receive(&mut manager, notifications).await?;
}
Cmd::Send { uuid, message } => {
let mut manager = Manager::load_registered(config_store)?;
let mut manager = Manager::load_registered(config_store).await?;
send(&message, &uuid, &mut manager).await?;
}
Cmd::SendToGroup {
message,
master_key,
} => {
let mut manager = Manager::load_registered(config_store)?;
let mut manager = Manager::load_registered(config_store).await?;

let timestamp = std::time::SystemTime::now()
.duration_since(UNIX_EPOCH)
Expand All @@ -519,7 +538,7 @@ async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
uuid,
mut profile_key,
} => {
let mut manager = Manager::load_registered(config_store)?;
let mut manager = Manager::load_registered(config_store).await?;
if profile_key.is_none() {
for contact in manager
.contacts()?
Expand Down Expand Up @@ -547,7 +566,7 @@ async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
Cmd::Unblock => unimplemented!(),
Cmd::UpdateContact => unimplemented!(),
Cmd::ListGroups => {
let manager = Manager::load_registered(config_store)?;
let manager = Manager::load_registered(config_store).await?;
for group in manager.groups()? {
match group {
Ok((
Expand All @@ -573,7 +592,7 @@ async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
}
}
Cmd::ListContacts => {
let manager = Manager::load_registered(config_store)?;
let manager = Manager::load_registered(config_store).await?;
for Contact {
name,
uuid,
Expand All @@ -585,11 +604,11 @@ async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
}
}
Cmd::Whoami => {
let manager = Manager::load_registered(config_store)?;
let manager = Manager::load_registered(config_store).await?;
println!("{:?}", &manager.whoami().await?);
}
Cmd::GetContact { ref uuid } => {
let manager = Manager::load_registered(config_store)?;
let manager = Manager::load_registered(config_store).await?;
match manager.contact_by_id(uuid)? {
Some(contact) => println!("{contact:#?}"),
None => eprintln!("Could not find contact for {uuid}"),
Expand All @@ -600,7 +619,7 @@ async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
phone_number,
ref name,
} => {
let manager = Manager::load_registered(config_store)?;
let manager = Manager::load_registered(config_store).await?;
for contact in manager
.contacts()?
.filter_map(Result::ok)
Expand All @@ -613,15 +632,15 @@ async fn run<C: Store>(subcommand: Cmd, config_store: C) -> anyhow::Result<()> {
}
#[cfg(feature = "quirks")]
Cmd::RequestSyncContacts => {
let mut manager = Manager::load_registered(config_store)?;
let mut manager = Manager::load_registered(config_store).await?;
manager.request_contacts_sync().await?;
}
Cmd::ListMessages {
group_master_key,
recipient_uuid,
from,
} => {
let manager = Manager::load_registered(config_store)?;
let manager = Manager::load_registered(config_store).await?;
let thread = match (group_master_key, recipient_uuid) {
(Some(master_key), _) => Thread::Group(master_key),
(_, Some(uuid)) => Thread::Contact(uuid),
Expand Down
3 changes: 0 additions & 3 deletions presage-store-sled/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ fn main() -> Result<()> {
// Build script does not automagically rerun when a new protobuf file is added.
// Directories are checked against mtime, which is platform specific
println!("cargo:rerun-if-changed=src/protobuf");
// Adding src/proto.rs means an extra `include!` will trigger a rerun. This is on best-effort
// basis.
println!("cargo:rerun-if-changed=src/proto.rs");

let input: Vec<_> = protobuf
.read_dir()
Expand Down
Loading

0 comments on commit c032e2a

Please sign in to comment.