show authorization code during device key approval

This commit is contained in:
2026-10-04 13:15:48 +07:00
parent 0bae051316
commit a8df0df0cd
4 changed files with 41 additions and 54 deletions
+23 -22
View File
@@ -39,7 +39,7 @@ pub enum DeviceEvent {
/// User have not setup encryption key
NotSet,
/// The device is requesting an encryption key
Requesting,
Requesting(SharedString),
/// An error occurred
Error(SharedString),
}
@@ -319,10 +319,7 @@ impl DeviceRegistry {
cx.background_spawn(async move {
// Construct an announcement event
let event = EventBuilder::new(Kind::Custom(10044), "")
.tags(vec![
Tag::custom("n", vec![n]),
Tag::custom("client", vec![CLIENT_NAME]),
])
.tag(Tag::custom("n", vec![n]))
.finalize_async(&signer)
.await?;
@@ -433,10 +430,7 @@ impl DeviceRegistry {
// No usable approval event found, construct a request event
let event = EventBuilder::new(Kind::Custom(4454), "")
.tags(vec![
Tag::custom("P", vec![app_pubkey]),
Tag::custom("client", vec![CLIENT_NAME]),
])
.tags(vec![Tag::custom("P", vec![app_pubkey])])
.finalize_async(&signer)
.await?;
@@ -475,8 +469,6 @@ impl DeviceRegistry {
let signer = nostr.read(cx).signer();
let app_keys_task = get_or_init_app_keys(cx);
cx.emit(DeviceEvent::Requesting);
self.tasks.push(cx.spawn(async move |this, cx| {
let app_keys = match app_keys_task.await {
Ok(app_keys) => app_keys,
@@ -488,6 +480,12 @@ impl DeviceRegistry {
}
};
this.update(cx, |_this, cx| {
cx.emit(DeviceEvent::Requesting(authorization_code(
&app_keys.public_key(),
)));
})?;
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
let public_key = signer.get_public_key_async().await?;
@@ -694,7 +692,9 @@ impl DeviceRegistry {
/// Build a notification for the encryption request.
fn notification(&self, event: Event, cx: &Context<Self>) -> Result<Notification, Error> {
const MSG: &str = "You've requested an encryption key from another device. \
Approve to allow Coop to share with it.";
Approve to allow Coop to share with it. Before approving, \
compare the code with the one shown on the requesting \
device.";
let requester = event
.tags
@@ -704,16 +704,10 @@ impl DeviceRegistry {
.and_then(|content| PublicKey::parse(content).ok())
.context("Request has no valid requester key")?;
let client_name = event
.tags
.iter()
.find(|tag| tag.kind() == "client")
.and_then(|tag| tag.content())
.map(|c| c.to_string());
let request = Announcement::new(requester, client_name);
let code = authorization_code(&requester);
let persons = PersonRegistry::global(cx);
let profile = persons.read(cx).get(&requester, cx);
let code_label = code.clone();
let entity = cx.entity().downgrade();
let loading = Rc::new(Cell::new(false));
@@ -776,7 +770,7 @@ impl DeviceRegistry {
.font_semibold()
.text_xs()
.text_color(cx.theme().text_muted)
.child(SharedString::from("Client:")),
.child(SharedString::from("Code:")),
)
.child(
div()
@@ -785,7 +779,7 @@ impl DeviceRegistry {
.px_2()
.rounded(cx.theme().radius)
.bg(cx.theme().elevated_surface_background)
.child(request.client_name()),
.child(code_label.clone()),
),
),
)
@@ -817,6 +811,13 @@ impl DeviceRegistry {
struct DeviceNotification;
/// The first eight hexadecimal characters of the client public key.
fn authorization_code(public_key: &PublicKey) -> SharedString {
let hex = public_key.to_hex();
let code = hex[..8].to_uppercase();
SharedString::from(format!("{} {}", &code[..4], &code[4..]))
}
/// Get or create new app keys (async, returns a task)
fn get_or_init_app_keys(cx: &App) -> Task<Result<Keys, Error>> {
let read = cx.read_credentials(CLIENT_NAME);