From 0a078b02b0c572e537dd6a11b6d4cc8844f406b9 Mon Sep 17 00:00:00 2001 From: Ry Racherbaumer Date: Mon, 2 Dec 2024 16:10:39 -0600 Subject: [PATCH] Lowercase address when checking association state (#1362) * Lowercase address when checking assoc state * Fix test helper types * Prepare release --- bindings_node/CHANGELOG.md | 5 ++ bindings_node/package.json | 2 +- bindings_node/src/client.rs | 89 ------------------------------ bindings_node/src/inbox_id.rs | 53 ++++++++++++++++++ bindings_node/test/helpers.ts | 5 +- bindings_node/test/inboxId.test.ts | 33 ++++++++++- 6 files changed, 94 insertions(+), 93 deletions(-) diff --git a/bindings_node/CHANGELOG.md b/bindings_node/CHANGELOG.md index 9c6b66051..3a46a8658 100644 --- a/bindings_node/CHANGELOG.md +++ b/bindings_node/CHANGELOG.md @@ -1,5 +1,10 @@ # @xmtp/node-bindings +## 0.0.28 + +- Removed `is_installation_authorized` and `is_address_authorized` from `Client` +- Lowercased `address` passed to `is_address_authorized` + ## 0.0.27 - Switched to Ubuntu 22.04 for builds diff --git a/bindings_node/package.json b/bindings_node/package.json index ba8c0e33f..a8a0907b0 100644 --- a/bindings_node/package.json +++ b/bindings_node/package.json @@ -1,6 +1,6 @@ { "name": "@xmtp/node-bindings", - "version": "0.0.27", + "version": "0.0.28", "repository": { "type": "git", "url": "git+https://git@github.com/xmtp/libxmtp.git", diff --git a/bindings_node/src/client.rs b/bindings_node/src/client.rs index 9a8e094e7..5190525f5 100644 --- a/bindings_node/src/client.rs +++ b/bindings_node/src/client.rs @@ -13,12 +13,9 @@ use tracing_subscriber::{fmt, prelude::*}; pub use xmtp_api_grpc::grpc_api_helper::Client as TonicApiClient; use xmtp_cryptography::signature::ed25519_public_key_to_address; use xmtp_id::associations::builder::SignatureRequest; -use xmtp_id::associations::MemberIdentifier; -use xmtp_mls::api::ApiClientWrapper; use xmtp_mls::builder::ClientBuilder; use xmtp_mls::groups::scoped_client::LocalScopedGroupClient; use xmtp_mls::identity::IdentityStrategy; -use xmtp_mls::retry::Retry; use xmtp_mls::storage::{EncryptedMessageStore, EncryptionKey, StorageOption}; use xmtp_mls::Client as MlsClient; use xmtp_proto::xmtp::mls::message_contents::DeviceSyncKind; @@ -303,90 +300,4 @@ impl Client { .map_err(ErrorWrapper::from)?; Ok(state.into_iter().map(Into::into).collect()) } - - #[napi] - pub async fn is_address_authorized(&self, inbox_id: String, address: String) -> Result { - self - .is_member_of_association_state(&inbox_id, &MemberIdentifier::Address(address)) - .await - } - - #[napi] - pub async fn is_installation_authorized( - &self, - inbox_id: String, - installation_id: Uint8Array, - ) -> Result { - self - .is_member_of_association_state( - &inbox_id, - &MemberIdentifier::Installation(installation_id.to_vec()), - ) - .await - } - - async fn is_member_of_association_state( - &self, - inbox_id: &str, - identifier: &MemberIdentifier, - ) -> Result { - let client = &self.inner_client; - let conn = self - .inner_client - .store() - .conn() - .map_err(ErrorWrapper::from)?; - - let association_state = client - .get_association_state(&conn, inbox_id, None) - .await - .map_err(ErrorWrapper::from)?; - - Ok(association_state.get(identifier).is_some()) - } -} - -#[napi] -pub async fn is_installation_authorized( - host: String, - inbox_id: String, - installation_id: Uint8Array, -) -> Result { - is_member_of_association_state( - &host, - &inbox_id, - &MemberIdentifier::Installation(installation_id.to_vec()), - ) - .await -} - -#[napi] -pub async fn is_address_authorized( - host: String, - inbox_id: String, - address: String, -) -> Result { - is_member_of_association_state(&host, &inbox_id, &MemberIdentifier::Address(address)).await -} - -async fn is_member_of_association_state( - host: &str, - inbox_id: &str, - identifier: &MemberIdentifier, -) -> Result { - let api_client = TonicApiClient::create(host, true) - .await - .map_err(ErrorWrapper::from)?; - let api_client = ApiClientWrapper::new(Arc::new(api_client), Retry::default()); - - let is_member = xmtp_mls::identity_updates::is_member_of_association_state( - &api_client, - inbox_id, - identifier, - None, - ) - .await - .map_err(ErrorWrapper::from)?; - - Ok(is_member) } diff --git a/bindings_node/src/inbox_id.rs b/bindings_node/src/inbox_id.rs index 34821514a..b9a4d34a9 100644 --- a/bindings_node/src/inbox_id.rs +++ b/bindings_node/src/inbox_id.rs @@ -1,8 +1,11 @@ use crate::ErrorWrapper; use napi::bindgen_prelude::Result; +use napi::bindgen_prelude::Uint8Array; use napi_derive::napi; +use std::sync::Arc; use xmtp_api_grpc::grpc_api_helper::Client as TonicApiClient; use xmtp_id::associations::generate_inbox_id as xmtp_id_generate_inbox_id; +use xmtp_id::associations::MemberIdentifier; use xmtp_mls::api::ApiClientWrapper; use xmtp_mls::retry::Retry; @@ -37,3 +40,53 @@ pub fn generate_inbox_id(account_address: String) -> Result { let result = xmtp_id_generate_inbox_id(&account_address, &1).map_err(ErrorWrapper::from)?; Ok(result) } + +#[napi] +pub async fn is_installation_authorized( + host: String, + inbox_id: String, + installation_id: Uint8Array, +) -> Result { + is_member_of_association_state( + &host, + &inbox_id, + &MemberIdentifier::Installation(installation_id.to_vec()), + ) + .await +} + +#[napi] +pub async fn is_address_authorized( + host: String, + inbox_id: String, + address: String, +) -> Result { + is_member_of_association_state( + &host, + &inbox_id, + &MemberIdentifier::Address(address.to_lowercase()), + ) + .await +} + +async fn is_member_of_association_state( + host: &str, + inbox_id: &str, + identifier: &MemberIdentifier, +) -> Result { + let api_client = TonicApiClient::create(host, true) + .await + .map_err(ErrorWrapper::from)?; + let api_client = ApiClientWrapper::new(Arc::new(api_client), Retry::default()); + + let is_member = xmtp_mls::identity_updates::is_member_of_association_state( + &api_client, + inbox_id, + identifier, + None, + ) + .await + .map_err(ErrorWrapper::from)?; + + Ok(is_member) +} diff --git a/bindings_node/test/helpers.ts b/bindings_node/test/helpers.ts index fc44c2229..989063d38 100644 --- a/bindings_node/test/helpers.ts +++ b/bindings_node/test/helpers.ts @@ -8,6 +8,7 @@ import { createClient as create, generateInboxId, getInboxIdForAddress, + LogLevel, SignatureRequestType, } from '../dist/index' @@ -44,7 +45,7 @@ export const createClient = async (user: User) => { user.account.address, undefined, undefined, - { level: 'info' } + { level: LogLevel.info } ) } @@ -81,7 +82,7 @@ export const encodeTextMessage = (text: string) => { } } -export function sleep(ms) { +export function sleep(ms: number) { return new Promise((resolve) => { setTimeout(resolve, ms) }) diff --git a/bindings_node/test/inboxId.test.ts b/bindings_node/test/inboxId.test.ts index bb771853f..d4e4e2139 100644 --- a/bindings_node/test/inboxId.test.ts +++ b/bindings_node/test/inboxId.test.ts @@ -1,6 +1,11 @@ import { describe, expect, it } from 'vitest' import { createRegisteredClient, createUser, TEST_API_URL } from '@test/helpers' -import { generateInboxId, getInboxIdForAddress } from '../dist/index' +import { + generateInboxId, + getInboxIdForAddress, + isAddressAuthorized, + isInstallationAuthorized, +} from '../dist/index' describe('generateInboxId', () => { it('should generate an inbox id', () => { @@ -32,3 +37,29 @@ describe('getInboxIdForAddress', () => { expect(inboxId).toBe(client.inboxId()) }) }) + +describe('isInstallationAuthorized', () => { + it('should return true if installation is authorized', async () => { + const user = createUser() + const client = await createRegisteredClient(user) + const isAuthorized = await isInstallationAuthorized( + TEST_API_URL, + client.inboxId(), + client.installationIdBytes() + ) + expect(isAuthorized).toBe(true) + }) +}) + +describe('isAddressAuthorized', () => { + it('should return true if address is authorized', async () => { + const user = createUser() + const client = await createRegisteredClient(user) + const isAuthorized = await isAddressAuthorized( + TEST_API_URL, + client.inboxId(), + user.account.address + ) + expect(isAuthorized).toBe(true) + }) +})