Skip to content
Merged
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 changes: 1 addition & 1 deletion nostr-java-api/src/main/java/nostr/api/NostrIF.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public interface NostrIF {
List<String> sendRequest(@NonNull Filters filters, @NonNull String subscriptionId, Map<String, String> relays);
List<String> sendRequest(@NonNull List<Filters> filtersList, @NonNull String subscriptionId);
List<String> sendRequest(@NonNull List<Filters> filtersList, @NonNull String subscriptionId, Map<String, String> relays);
NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable) throws Exception;
NostrIF sign(@NonNull Identity identity, @NonNull ISignable signable);
boolean verify(@NonNull GenericEvent event);
Identity getSender();
Map<String, String> getRelays();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
import nostr.config.Constants;
import nostr.event.impl.GenericEvent;
import nostr.id.Identity;
import nostr.id.SigningException;
import nostr.base.ISignable;
import nostr.base.Signature;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

Expand Down Expand Up @@ -41,4 +49,40 @@ void sendEventReturnsEmptyListWhenSigned() {
List<String> responses = client.sendEvent(event);
assertTrue(responses.isEmpty());
}

@Test
// Verifies that SigningException bubbles up from the client when signing fails
void signPropagatesSigningException() {
String invalidPriv = "0000000000000000000000000000000000000000000000000000000000000000";
Identity identity = Identity.create(invalidPriv);

ISignable signable = new ISignable() {
private Signature signature;

@Override
public Signature getSignature() {
return signature;
}

@Override
public void setSignature(Signature signature) {
this.signature = signature;
}

@Override
public Consumer<Signature> getSignatureConsumer() {
return this::setSignature;
}

@Override
public Supplier<ByteBuffer> getByteArraySupplier() {
return () -> ByteBuffer.wrap("msg".getBytes(StandardCharsets.UTF_8));
}
};

NoteService service = Mockito.mock(NoteService.class);
NostrSpringWebSocketClient client = new NostrSpringWebSocketClient(service);

assertThrows(SigningException.class, () -> client.sign(identity, signable));
}
}
6 changes: 3 additions & 3 deletions nostr-java-id/src/main/java/nostr/id/Identity.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ public PublicKey getPublicKey() {
return cachedPublicKey;
}

// TODO: exceptions refactor
/**
* Signs the supplied {@link ISignable} using this identity's private key.
* The resulting {@link Signature} is returned and also provided to the
* signable's signature consumer.
*
* @param signable the entity to sign
* @return the generated signature
* @throws Exception if the signature cannot be created
* @throws IllegalStateException if the SHA-256 algorithm is unavailable
* @throws SigningException if the signature cannot be created
*/
public Signature sign(@NonNull ISignable signable) {
try {
Expand All @@ -117,7 +117,7 @@ public Signature sign(@NonNull ISignable signable) {
throw new IllegalStateException("SHA-256 algorithm not available", ex);
} catch (Exception ex) {
log.error("Signing failed", ex);
throw new IllegalArgumentException("Failed to sign with provided key", ex);
throw new SigningException("Failed to sign with provided key", ex);
}
}

Expand Down
10 changes: 10 additions & 0 deletions nostr-java-id/src/main/java/nostr/id/SigningException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package nostr.id;

import lombok.experimental.StandardException;

/**
* Exception thrown when signing an {@link nostr.base.ISignable} fails.
*/
@StandardException
public class SigningException extends RuntimeException {
}
13 changes: 7 additions & 6 deletions nostr-java-id/src/test/java/nostr/id/IdentityTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,11 @@ public void testGetPublicKeyFailure() {
Assertions.assertThrows(IllegalStateException.class, identity::getPublicKey);
}

@Test
public void testSignWithInvalidKeyFails() {
String invalidPriv = "0000000000000000000000000000000000000000000000000000000000000000";
Identity identity = Identity.create(invalidPriv);
@Test
// Ensures that signing with an invalid private key throws SigningException
public void testSignWithInvalidKeyFails() {
String invalidPriv = "0000000000000000000000000000000000000000000000000000000000000000";
Identity identity = Identity.create(invalidPriv);

ISignable signable = new ISignable() {
private Signature signature;
Expand All @@ -140,6 +141,6 @@ public Supplier<ByteBuffer> getByteArraySupplier() {
}
};

Assertions.assertThrows(IllegalArgumentException.class, () -> identity.sign(signable));
}
Assertions.assertThrows(SigningException.class, () -> identity.sign(signable));
}
}
Loading