XEP-0313 MAM: missing attribute "by" on stanza-id element
diff --git a/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/MessageStanzaWithId.java b/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/MessageStanzaWithId.java
index 5de0fd2..73ad748 100644
--- a/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/MessageStanzaWithId.java
+++ b/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/MessageStanzaWithId.java
@@ -46,10 +46,6 @@
 
     private final Entity archiveId;
 
-    public MessageStanzaWithId(ArchivedMessage archivedMessage) {
-        this(archivedMessage, null);
-    }
-
     public MessageStanzaWithId(ArchivedMessage archivedMessage, Entity archiveId) {
         this.archivedMessage = requireNonNull(archivedMessage);
         this.archiveId = archiveId;
diff --git a/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserMessageStanzaBroker.java b/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserMessageStanzaBroker.java
index b818253..4fcc1bc 100644
--- a/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserMessageStanzaBroker.java
+++ b/server/extensions/xep0313-mam/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserMessageStanzaBroker.java
@@ -108,8 +108,7 @@
             addToSenderArchive(messageStanza, sessionContext);
             return messageStanza;
         } else {
-            return addToReceiverArchive(messageStanza).map(MessageStanzaWithId::new).map(MessageStanzaWithId::toStanza)
-                    .orElse(stanza);
+            return addToReceiverArchive(messageStanza).map(MessageStanzaWithId::toStanza).orElse(stanza);
         }
     }
 
@@ -125,7 +124,7 @@
         senderArchive.get().archive(new SimpleMessage(messageStanza));
     }
 
-    private Optional<ArchivedMessage> addToReceiverArchive(MessageStanza messageStanza) {
+    private Optional<MessageStanzaWithId> addToReceiverArchive(MessageStanza messageStanza) {
         // Servers that expose archive messages of sent/received messages on behalf of
         // local users MUST expose these archives to the user on the user's bare JID.
         Entity receiverArchiveId = requireNonNull(messageStanza.getTo(), "No 'to' found in " + messageStanza)
@@ -136,7 +135,8 @@
             return Optional.empty();
         }
 
-        return Optional.ofNullable(receiverArchive.get().archive(new SimpleMessage(messageStanza)));
+        ArchivedMessage archivedMessage = receiverArchive.get().archive(new SimpleMessage(messageStanza));
+        return Optional.of(new MessageStanzaWithId(archivedMessage, receiverArchiveId));
     }
 
     private MessageArchives messageArchives() {
diff --git a/server/extensions/xep0313-mam/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserArchiveTest.java b/server/extensions/xep0313-mam/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserArchiveTest.java
index 9e1fbb4..ba577ed 100644
--- a/server/extensions/xep0313-mam/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserArchiveTest.java
+++ b/server/extensions/xep0313-mam/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0313_mam/user/UserArchiveTest.java
@@ -22,7 +22,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -69,6 +68,25 @@
     }
 
     @Test
+    public void receivedArchivedMessageShouldHaveAStanzaId() throws SmackException.NotConnectedException, InterruptedException {
+        AtomicReference<Message> carolReceivedMessage = new AtomicReference<>();
+        ChatManager.getInstanceFor(carol())
+                .addIncomingListener((from, message, chat) -> carolReceivedMessage.set(message));
+
+        Chat chatFromAliceToCarol = ChatManager.getInstanceFor(alice()).chatWith(carol().getUser().asEntityBareJid());
+        chatFromAliceToCarol.send("Hello carol");
+
+        Thread.sleep(200);
+
+        assertNotNull(carolReceivedMessage.get());
+
+        StanzaIdElement stanzaIdElement = extractStanzaId(carolReceivedMessage.get());
+        assertNotNull(stanzaIdElement);
+        assertNotNull(stanzaIdElement.getId());
+        assertEquals(carol().getUser().asEntityBareJid(), stanzaIdElement.getBy());
+    }
+
+    @Test
     public void sendMessageAndQuerySenderAndReceiverArchive()
             throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException,
             XMPPException.XMPPErrorException, SmackException.NoResponseException {
@@ -89,7 +107,7 @@
         assertEquals(alice().getUser(), toCarolArchivedMessage.getFrom());
         assertEquals(carol().getUser().asEntityBareJidOrThrow(),
                 toCarolArchivedMessage.getTo().asEntityBareJidOrThrow());
-        String toCarolArchivedMessageId = extractStanzaId(toCarolArchivedMessage);
+        String toCarolArchivedMessageId = extractStanzaId(toCarolArchivedMessage).getId();
 
         MamManager.MamQuery carolArchive = MamManager.getInstanceFor(carol()).queryArchive(fullQuery);
 
@@ -100,10 +118,10 @@
         assertEquals(alice().getUser(), fromAliceArchivedMessage.getFrom());
         assertEquals(carol().getUser().asEntityBareJidOrThrow(),
                 fromAliceArchivedMessage.getTo().asEntityBareJidOrThrow());
-        String fromAliceArchivedMessageId = extractStanzaId(fromAliceArchivedMessage);
+        String fromAliceArchivedMessageId = extractStanzaId(fromAliceArchivedMessage).getId();
 
         assertFalse(toCarolArchivedMessageId.equals(fromAliceArchivedMessageId));
-        assertEquals(extractStanzaId(carolReceivedMessage.get()), fromAliceArchivedMessageId);
+        assertEquals(extractStanzaId(carolReceivedMessage.get()).getId(), fromAliceArchivedMessageId);
     }
 
     @Test
@@ -193,10 +211,10 @@
         assertEquals("Hello carol", carolReceivedMessage.get().getBody());
 
         Message archivedMessage = fetchUniqueArchivedMessage(carol());
-        String storedStanzaId = extractStanzaId(archivedMessage);
+        String storedStanzaId = extractStanzaId(archivedMessage).getId();
         assertNotNull(storedStanzaId);
 
-        String receivedStanzaId = extractStanzaId(carolReceivedMessage.get());
+        String receivedStanzaId = extractStanzaId(carolReceivedMessage.get()).getId();
 
         assertEquals(storedStanzaId, receivedStanzaId);
     }
@@ -220,7 +238,7 @@
         Thread.sleep(200);
 
         Message archivedMessage = fetchUniqueArchivedMessage(carol());
-        String storedStanzaId = extractStanzaId(archivedMessage);
+        String storedStanzaId = extractStanzaId(archivedMessage).getId();
         assertNotNull(storedStanzaId);
     }
 
@@ -284,14 +302,14 @@
         return archive.getMessages().get(0);
     }
 
-    private String extractStanzaId(Stanza stanza) {
+    private StanzaIdElement extractStanzaId(Stanza stanza) {
         assertNotNull(stanza);
         ExtensionElement extensionElement = stanza.getExtension(NamespaceURIs.XEP0359_STANZA_IDS);
         if (!(extensionElement instanceof StanzaIdElement)) {
             fail("No stanza id in " + stanza);
         }
 
-        return ((StanzaIdElement) extensionElement).getId();
+        return (StanzaIdElement) extensionElement;
     }
 
 }