conversejs / converse.js

Web-based XMPP/Jabber chat client written in JavaScript
http://conversejs.org
Mozilla Public License 2.0
3.07k stars 769 forks source link

Only the first annoucement from a component is displayed during a single session #2930

Open truenicoco opened 2 years ago

truenicoco commented 2 years ago

Describe the bug When a component sends messages, only the first is correctly parsed by conversejs. The following ones do not appear unless the browser window is refreshed.

To Reproduce Steps to reproduce the behaviour (there might be other ways, but this is what I did)

  1. Receive messages from a component (for instance with this slixmpp example, changing ClientXMPP to ComponentXMPP)
  2. Only the first message sent by the component is shown in conversejs
  3. Refresh the page
  4. See all the messages actually sent by the components (maybe through MAM?)

Expected behavior All messages should be displayed

Environment (please complete the following information):

Additional context

An example of message stanza that only appeared after reloading the page:

<message type="chat" to="test@localhost/converse.js-99856373" from='dummy.localhost' id="71212abb240443fa91d102ebdfbf3b68">
 <origin-id xmlns="urn:xmpp:sid:0" id="71212abb240443fa91d102ebdfbf3b68" />
 <body>prout, World!</body>
 <request xmlns="urn:xmpp:receipts" />
</message>

And the corresponding JS console log

2022-05-25T08:01:54.455Z INFO: handleMessageStanza: Ignoring incoming server message from JID: dummy.localhost <empty string> [log.js:72:19](webpack://converse.js/src/headless/log.js)
Uncaught TypeError: this.model.rosterContactAdded is undefined
    initialize user-details.js:34
    Iv view.js:45
    s helpers.js:32
    s helpers.js:32
    create api.js:46
    show api.js:26
    showUserModal message.js:224
    handleEvent lit-html.ts:2047
[user-details.js:34:8](webpack://converse.js/src/modals/user-details.js)
Uncaught (in promise) TypeError: bu.omemo is undefined
    initialize fingerprints.js:14
    connectedCallback element.js:14
    insertIntoDOM base.js:52
    initialize base.js:36
    initialize user-details.js:33
    Iv view.js:45
    s helpers.js:32
    s helpers.js:32
    create api.js:46
    show api.js:26
    showUserModal message.js:224
    handleEvent lit-html.ts:2047
[fingerprints.js:14:8](webpack://converse.js/src/plugins/omemo/fingerprints.js)
 2022-05-25T08:06:30.639Z INFO: handleMessageStanza: Ignoring incoming server message from JID: dummy.localhost <empty string>
jcbrand commented 2 years ago

This appears to be the reason:

2022-05-25T08:01:54.455Z INFO: handleMessageStanza: Ignoring incoming server message from JID: dummy.localhost <empty string> [log.js:72:19](webpack://converse.js/src/headless/log.js)

https://github.com/conversejs/converse.js/blob/1ad6de2dd6a0b56fc84a65a4bddf7647e595fba4/src/headless/plugins/chat/utils.js#L112

The message gets ignored because isServerMessage returns true.

I would expect the message to appear as a headline, to which the user cannot respond (i.e. a read-only feed).

Do you expect users to be able to write messages back to the component?

jcbrand commented 2 years ago

Here is the headline code where incoming messages are handled: https://github.com/conversejs/converse.js/blob/master/src/headless/plugins/headlines/utils.js#L10

I would expect the component messages to be handled there and then appear in a Headlines box.

truenicoco commented 2 years ago
I would expect the component messages to be handled there and then appear in a Headlines box.

Weirdly enough, only the first message sent by the component seems to be correctly parsed.

Do you expect users to be able to write messages back to the component?

Conversations and Gajim allows this, but I guess that's non standard and it is OK not to be able to answer since conversejs supports ad-hoc commands, which seems cleaner. But showing only the first 'headline' looks like a bug on converse side.

Ignoring incoming server message from JID: dummy.localhost

Does that mean the message's body is supposedly empty?

jcbrand commented 2 years ago

Can you show a screenshot of where the message appears?

Does that mean the message's body is supposedly empty?

No, I think it means that Converse has determined that the message is from a server (or server component) and not a user and therefore doesn't show it in a normal chat (but it should instead show it in a headlines feed for that server/component).

jcbrand commented 2 years ago

Conversations and Gajim allows this

Ok, well maybe I should update the code then. A message with type headline means that you can't reply, but IIRC Prosody doesn't use headline for server messages because then they're not stored in MAM, so they use chat and I then added code to still check if they're from a server or component and treat them as headline messages (i.e. you can't reply to them).

I think you're presenting a use-case where you can reply... and to be honest, type chat does imply two-way communication, so perhaps I should revisit the logic of that code.

truenicoco commented 2 years ago

Can you show a screenshot of where the message appears?

On this screenshot, I executed the command with "hi" as "Your greeting", then "thiswontwork":

Screenshot_20220530_164515

After a refresh, I think the message gets pulled from MAM because it appears:

image


I also tried sending messages as "headline type" instead of "chat type", and it seems that conversejs just does not display anything this way, without any message in the console. Similarly, messages appear after a refresh though :/

image

jcbrand commented 2 years ago

Thanks, so from your screenshot I see that the message is indeed treated as a headline message.

One more thing please.

Can you set loglevel to true and then open the browser's developer console. Then in the console turn on verbose logging?

You should then see the XML stanzas being sent between Converse and the XMPP server.

Please reproduce the above exchange one more time, copy the stanzas and paste them here. From that I should be able to make a test with which I can reproduce the bug and then fix it.

truenicoco commented 2 years ago

I am unsure how to set loglevel=true. Do I have to build/webpack/js stuff? Right now I am using mod_conversejs from prosody to do the tests. I tried passing conversejs_options = { debug = true; loglevel = true; } in prosody's config, but it wasn't more verbose.

jcbrand commented 2 years ago

Sorry, I meant loglevel = 'debug'

Should work fine by passing it via conversejs_options in Prosody's config.

truenicoco commented 2 years ago

It does not seem to work, this is what I see during login:

image

(sorry about firefox's error colors...)

And not much more during the component messages test.

jcbrand commented 2 years ago

See here: https://conversejs.org/docs/html/configuration.html#loglevel

Check that verbose logging is turned on in the developer console.

That error is completely unreadable to me, so I can't tell what's going on.

truenicoco commented 2 years ago

The error happens on loading the page and is not related IMHO.

Anyway, #converse?loglevel=debug worked for me.

I think there are several things going on here.

Some headlines are not displayed

I cannot really understand why, but one example:

image

<message to="test@localhost/converse.js-10125775" xmlns="jabber:client" type="headline" xml:lang="en" id="162186f2dbfe4bb0b5cd05536e65e5c1" from="dummy.localhost">
    <origin-id id="162186f2dbfe4bb0b5cd05536e65e5c1" xmlns="urn:xmpp:sid:0" />
    <body>wof, World!</body>
    <request xmlns="urn:xmpp:receipts" />
</message>

And after refreshing the page/relogging in:

image

Conversejs reuses the same session ID for adhoc commands even when a command has completed

This triggers an error from my component, and I think it is incorrect behaviour from converse. I just realized that now, but I guess is fairly important here:

2022-05-31T08:53:41.125Z DEBUG:<iq from="test@localhost/converse.js-10125775" to="dummy.localhost" type="get" id="78be646f-6284-4580-b7e9-04c26cbf5644:sendIQ">
    <query node="http://jabber.org/protocol/commands" />
</iq>log.js:70:19
 2022-05-31T08:53:41.130Z DEBUG:<iq to="test@localhost/converse.js-10125775" xmlns="jabber:client" type="result" xml:lang="en" id="78be646f-6284-4580-b7e9-04c26cbf5644:sendIQ" from="dummy.localhost">
    <query node="http://jabber.org/protocol/commands" xmlns="http://jabber.org/protocol/disco#items">
        <item jid="dummy.localhost" node="greeting" name="Greeting" />
        <item jid="dummy.localhost" node="registration" name="Register" />
    </query>
</iq>log.js:70:19
 2022-05-31T08:53:44.176Z DEBUG:<iq type="set" to="dummy.localhost" id="37e061d1-3849-48dd-bbb3-926d80f3b8bc:sendIQ">
    <command node="greeting" action="execute" />
</iq>log.js:70:19
 2022-05-31T08:53:44.182Z DEBUG:<iq to="test@localhost/converse.js-10125775" xmlns="jabber:client" type="result" xml:lang="en" id="37e061d1-3849-48dd-bbb3-926d80f3b8bc:sendIQ" from="dummy.localhost">
    <command status="executing" node="greeting" sessionid="1653987224.1785727-2d9aad84ce64488bbfe73dbbe5f272e2" xmlns="http://jabber.org/protocol/commands">
        <actions>
            <complete />
        </actions>
        <x type="form" xmlns="jabber:x:data">
            <title>Greeting</title>
            <instructions>Send a custom greeting to a JID</instructions>
            <field type="text-single" label="Your greeting" var="greeting" />
        </x>
    </command>
</iq>log.js:70:19
 2022-05-31T08:53:49.459Z DEBUG:<iq to="dummy.localhost" type="set" id="5fb2ec0e-ad0d-4d21-8275-60b183d40097:sendIQ">
    <command sessionid="1653987224.1785727-2d9aad84ce64488bbfe73dbbe5f272e2" node="greeting">
        <x type="submit">
            <field var="greeting">
                <value>FIRST</value>
            </field>
        </x>
    </command>
</iq>log.js:70:19
 2022-05-31T08:53:49.466Z DEBUG:<message to="test@localhost/converse.js-10125775" xmlns="jabber:client" type="headline" xml:lang="en" id="5e4f4d1976ed4706a5d17fb96579480e" from="dummy.localhost">
    <origin-id id="5e4f4d1976ed4706a5d17fb96579480e" xmlns="urn:xmpp:sid:0" />
    <body>FIRST, World!</body>
    <request xmlns="urn:xmpp:receipts" />
</message>log.js:70:19
 2022-05-31T08:53:49.470Z DEBUG:<iq to="test@localhost/converse.js-10125775" xmlns="jabber:client" type="result" xml:lang="en" id="5fb2ec0e-ad0d-4d21-8275-60b183d40097:sendIQ" from="dummy.localhost">
    <command status="completed" node="greeting" sessionid="1653987224.1785727-2d9aad84ce64488bbfe73dbbe5f272e2" xmlns="http://jabber.org/protocol/commands" />
</iq>log.js:70:19
 2022-05-31T08:53:54.310Z DEBUG:<iq to="dummy.localhost" type="set" id="01fa353a-d783-47f2-9ce9-09a0384d4c43:sendIQ">
    <command sessionid="1653987224.1785727-2d9aad84ce64488bbfe73dbbe5f272e2" node="greeting">
        <x type="submit">
            <field var="greeting">
                <value>SECOND</value>
            </field>
        </x>
    </command>
</iq>log.js:70:19
 2022-05-31T08:53:54.315Z DEBUG:<iq to="test@localhost/converse.js-10125775" xmlns="jabber:client" type="error" xml:lang="en" id="01fa353a-d783-47f2-9ce9-09a0384d4c43:sendIQ" from="dummy.localhost">
    <error type="cancel">
        <undefined-condition xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
        <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Slixmpp got into trouble.</text>
    </error>
</iq>log.js:70:19

I think a 'completed' command should close the command form in converse ui, and clicking the command again should initiate a new session.

Converse does not like messages of type "chat" sent by components

2022-05-31T08:58:56.357Z DEBUG:
<message to="test@localhost/converse.js-10125775" xmlns="jabber:client" type="chat" xml:lang="en" id="c3f37f43e93b45f2b1cb01985882e46c" from="dummy.localhost">
    <origin-id id="c3f37f43e93b45f2b1cb01985882e46c" xmlns="urn:xmpp:sid:0" />
    <body>not a headline, World!</body>
    <request xmlns="urn:xmpp:receipts" />
    <stanza-id by="test@localhost" id="aNpuaZ9lOoXMCl_qN4Qpi3Gp" xmlns="urn:xmpp:sid:0" />
</message>
2022-05-31T08:58:56.358Z INFO: handleMessageStanza: Ignoring incoming server message from JID: dummy.localhost<empty string>

This message does not show up anywhere, until I refresh/relogin then I also see it as a headline, with a weird intent.

image

I did not manage to see where it appears in the JS console, but I am guessing it must be a MAM thing.