Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
9d77a4ef
Commit
9d77a4ef
authored
Nov 18, 2018
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes #129 Add support for XEP-0156.
Only XML is supported for now.
parent
54e9c51a
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
335 additions
and
263 deletions
+335
-263
CHANGES.md
CHANGES.md
+7
-0
docs/source/configuration.rst
docs/source/configuration.rst
+18
-2
spec/bookmarks.js
spec/bookmarks.js
+24
-61
spec/login.js
spec/login.js
+2
-2
spec/register.js
spec/register.js
+11
-11
spec/roomslist.js
spec/roomslist.js
+2
-4
spec/smacks.js
spec/smacks.js
+1
-1
src/converse-chatview.js
src/converse-chatview.js
+1
-1
src/converse-controlbox.js
src/converse-controlbox.js
+15
-13
src/converse-dragresize.js
src/converse-dragresize.js
+1
-1
src/converse-minimize.js
src/converse-minimize.js
+2
-5
src/converse-omemo.js
src/converse-omemo.js
+2
-2
src/converse-register.js
src/converse-register.js
+4
-3
src/headless/converse-bosh.js
src/headless/converse-bosh.js
+18
-13
src/headless/converse-chatboxes.js
src/headless/converse-chatboxes.js
+2
-2
src/headless/converse-core.js
src/headless/converse-core.js
+144
-65
src/headless/converse-muc.js
src/headless/converse-muc.js
+1
-1
src/headless/utils/core.js
src/headless/utils/core.js
+9
-0
tests/mock.js
tests/mock.js
+71
-76
No files found.
CHANGES.md
View file @
9d77a4ef
...
@@ -2,11 +2,18 @@
...
@@ -2,11 +2,18 @@
## 6.0.0 (Unreleased)
## 6.0.0 (Unreleased)
-
#129: Add support for XEP-0156: Disovering Alternative XMPP Connection Methods. Only XML is supported for now.
-
#1691 Fix
`collection.chatbox is undefined`
errors
-
#1691 Fix
`collection.chatbox is undefined`
errors
-
Prevent editing of sent file uploads.
-
Prevent editing of sent file uploads.
### Breaking changes
### Breaking changes
-
In order to add support for XEP-0156, the XMPP connection needs to be created
only once we know the JID of the user that's logging in. This means that the
[
connectionInitialized
](
https://conversejs.org/docs/html/api/-_converse.html#event:connectionInitialized
)
event now fires much later than before. Plugins that rely on
`connectionInitialized`
being triggered before the user's JID has been provided will need to be updated.
-
The following API methods now return promises:
-
The following API methods now return promises:
*
`_converse.api.chats.get`
*
`_converse.api.chats.get`
*
`_converse.api.chats.create`
*
`_converse.api.chats.create`
...
...
docs/source/configuration.rst
View file @
9d77a4ef
...
@@ -639,6 +639,23 @@ The default chat status that the user wil have. If you for example set this to
...
@@ -639,6 +639,23 @@ The default chat status that the user wil have. If you for example set this to
``'chat'``, then Converse will send out a presence stanza with ``"show"``
``'chat'``, then Converse will send out a presence stanza with ``"show"``
set to ``'chat'`` as soon as you've been logged in.
set to ``'chat'`` as soon as you've been logged in.
discover_connection_methods
---------------------------
* Default: ``false``
Use `XEP-0156 <https://xmpp.org/extensions/xep-0156.html>`_ to discover whether
the XMPP host for the current user advertises any Websocket or BOSH connection
URLs that can be used.
If this is set to ``false``, then a `websocket_url`_ or `bosh_service_url`_ need to be
set.
Currently only the XML encoded host-meta resource is supported as shown in
`Example 2 under section 3.3 <https://xmpp.org/extensions/xep-0156.html#httpexamples>`_.
domain_placeholder
domain_placeholder
------------------
------------------
...
@@ -647,8 +664,6 @@ domain_placeholder
...
@@ -647,8 +664,6 @@ domain_placeholder
The placeholder text shown in the domain input on the registration form.
The placeholder text shown in the domain input on the registration form.
emoji_image_path
emoji_image_path
----------------
----------------
...
@@ -1624,6 +1639,7 @@ Allows you to show or hide buttons on the chatboxes' toolbars.
...
@@ -1624,6 +1639,7 @@ Allows you to show or hide buttons on the chatboxes' toolbars.
.. _`websocket-url`:
.. _`websocket-url`:
websocket_url
websocket_url
-------------
-------------
...
...
spec/bookmarks.js
View file @
9d77a4ef
...
@@ -404,8 +404,8 @@
...
@@ -404,8 +404,8 @@
it
(
"
can be retrieved from the XMPP server
"
,
mock
.
initConverse
(
it
(
"
can be retrieved from the XMPP server
"
,
mock
.
initConverse
(
{
'
connection
'
:
[
'
send
'
]}
,
[
'
chatBoxesFetched
'
,
'
roomsPanelRendered
'
,
'
rosterGroupsFetched
'
],
{},
null
,
[
'
chatBoxesFetched
'
,
'
roomsPanelRendered
'
,
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
await
test_utils
.
waitUntilDiscoConfirmed
(
await
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
_converse
,
_converse
.
bare_jid
,
...
@@ -421,25 +421,12 @@
...
@@ -421,25 +421,12 @@
* </pubsub>
* </pubsub>
* </iq>
* </iq>
*/
*/
let
IQ_id
;
const
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
const
call
=
await
u
.
waitUntil
(()
=>
const
sent_stanza
=
await
u
.
waitUntil
(
_
.
filter
(
()
=>
IQ_stanzas
.
filter
(
s
=>
sizzle
(
'
items[node="storage:bookmarks"]
'
,
s
).
length
).
pop
());
_converse
.
connection
.
send
.
calls
.
all
(),
call
=>
{
const
stanza
=
call
.
args
[
0
];
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
if
(
sizzle
(
'
items[node="storage:bookmarks"]
'
,
stanza
).
length
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
}
}
).
pop
()
);
expect
(
Strophe
.
serialize
(
call
.
args
[
0
]
)).
toBe
(
expect
(
Strophe
.
serialize
(
sent_stanza
)).
toBe
(
`<iq from="romeo@montague.lit/orchard" id="
${
IQ_id
}
" type="get" xmlns="jabber:client">`
+
`<iq from="romeo@montague.lit/orchard" id="
${
sent_stanza
.
getAttribute
(
'
id
'
)
}
" type="get" xmlns="jabber:client">`
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"/>
'
+
'
<items node="storage:bookmarks"/>
'
+
'
</pubsub>
'
+
'
</pubsub>
'
+
...
@@ -469,7 +456,7 @@
...
@@ -469,7 +456,7 @@
expect
(
_converse
.
bookmarks
.
models
.
length
).
toBe
(
0
);
expect
(
_converse
.
bookmarks
.
models
.
length
).
toBe
(
0
);
spyOn
(
_converse
.
bookmarks
,
'
onBookmarksReceived
'
).
and
.
callThrough
();
spyOn
(
_converse
.
bookmarks
,
'
onBookmarksReceived
'
).
and
.
callThrough
();
var
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
var
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
sent_stanza
.
getAttribute
(
'
id
'
)
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
...
@@ -495,7 +482,7 @@
...
@@ -495,7 +482,7 @@
describe
(
"
The rooms panel
"
,
function
()
{
describe
(
"
The rooms panel
"
,
function
()
{
it
(
"
shows a list of bookmarks
"
,
mock
.
initConverse
(
it
(
"
shows a list of bookmarks
"
,
mock
.
initConverse
(
{
'
connection
'
:
[
'
send
'
]}
,
[
'
rosterGroupsFetched
'
],
{},
null
,
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
await
test_utils
.
waitUntilDiscoConfirmed
(
await
test_utils
.
waitUntilDiscoConfirmed
(
...
@@ -505,31 +492,19 @@
...
@@ -505,31 +492,19 @@
);
);
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
let
IQ_id
;
const
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
const
call
=
await
u
.
waitUntil
(()
=>
const
sent_stanza
=
await
u
.
waitUntil
(
_
.
filter
(
()
=>
IQ_stanzas
.
filter
(
s
=>
sizzle
(
'
items[node="storage:bookmarks"]
'
,
s
).
length
).
pop
());
_converse
.
connection
.
send
.
calls
.
all
(),
call
=>
{
expect
(
Strophe
.
serialize
(
sent_stanza
)).
toBe
(
const
stanza
=
call
.
args
[
0
];
`<iq from="romeo@montague.lit/orchard" id="
${
sent_stanza
.
getAttribute
(
'
id
'
)}
" type="get" xmlns="jabber:client">`
+
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
if
(
sizzle
(
'
items[node="storage:bookmarks"]
'
,
stanza
).
length
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
}
}
).
pop
()
);
expect
(
Strophe
.
serialize
(
call
.
args
[
0
])).
toBe
(
`<iq from="romeo@montague.lit/orchard" id="
${
IQ_id
}
" type="get" xmlns="jabber:client">`
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"/>
'
+
'
<items node="storage:bookmarks"/>
'
+
'
</pubsub>
'
+
'
</pubsub>
'
+
'
</iq>
'
'
</iq>
'
);
);
const
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
const
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
sent_stanza
.
getAttribute
(
'
id
'
)
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
...
@@ -583,7 +558,7 @@
...
@@ -583,7 +558,7 @@
it
(
"
remembers the toggle state of the bookmarks list
"
,
mock
.
initConverse
(
it
(
"
remembers the toggle state of the bookmarks list
"
,
mock
.
initConverse
(
{
'
connection
'
:
[
'
send
'
]}
,
[
'
rosterGroupsFetched
'
],
{},
null
,
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
...
@@ -593,31 +568,19 @@
...
@@ -593,31 +568,19 @@
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
);
);
let
IQ_id
;
const
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
const
call
=
await
u
.
waitUntil
(()
=>
const
sent_stanza
=
await
u
.
waitUntil
(
_
.
filter
(
()
=>
IQ_stanzas
.
filter
(
s
=>
sizzle
(
'
items[node="storage:bookmarks"]
'
,
s
).
length
).
pop
());
_converse
.
connection
.
send
.
calls
.
all
(),
call
=>
{
expect
(
Strophe
.
serialize
(
sent_stanza
)).
toBe
(
const
stanza
=
call
.
args
[
0
];
`<iq from="romeo@montague.lit/orchard" id="
${
sent_stanza
.
getAttribute
(
'
id
'
)}
" type="get" xmlns="jabber:client">`
+
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
if
(
sizzle
(
'
items[node="storage:bookmarks"]
'
,
stanza
).
length
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
}
}
).
pop
()
);
expect
(
Strophe
.
serialize
(
call
.
args
[
0
])).
toBe
(
`<iq from="romeo@montague.lit/orchard" id="
${
IQ_id
}
" type="get" xmlns="jabber:client">`
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"/>
'
+
'
<items node="storage:bookmarks"/>
'
+
'
</pubsub>
'
+
'
</pubsub>
'
+
'
</iq>
'
'
</iq>
'
);
);
const
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
const
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
sent_stanza
.
getAttribute
(
'
id
'
)
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
...
...
spec/login.js
View file @
9d77a4ef
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
it
(
"
contains a checkbox to indicate whether the computer is trusted or not
"
,
it
(
"
contains a checkbox to indicate whether the computer is trusted or not
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
allow_registration
:
false
},
allow_registration
:
false
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
...
@@ -42,7 +42,7 @@
...
@@ -42,7 +42,7 @@
it
(
"
checkbox can be set to false by default
"
,
it
(
"
checkbox can be set to false by default
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
trusted
:
false
,
trusted
:
false
,
allow_registration
:
false
},
allow_registration
:
false
},
...
...
spec/register.js
View file @
9d77a4ef
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
it
(
"
is not available unless allow_registration=true
"
,
it
(
"
is not available unless allow_registration=true
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
allow_registration
:
false
},
allow_registration
:
false
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
it
(
"
can be opened by clicking on the registration tab
"
,
it
(
"
can be opened by clicking on the registration tab
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
allow_registration
:
true
},
allow_registration
:
true
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
...
@@ -45,18 +45,18 @@
...
@@ -45,18 +45,18 @@
it
(
"
allows the user to choose an XMPP provider's domain
"
,
it
(
"
allows the user to choose an XMPP provider's domain
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
allow_registration
:
true
},
allow_registration
:
true
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
spyOn
(
Strophe
.
Connection
.
prototype
,
'
connect
'
);
await
u
.
waitUntil
(()
=>
_
.
get
(
_converse
.
chatboxviews
.
get
(
'
controlbox
'
),
'
registerpanel
'
));
await
u
.
waitUntil
(()
=>
_
.
get
(
_converse
.
chatboxviews
.
get
(
'
controlbox
'
),
'
registerpanel
'
));
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
const
cbview
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
);
const
cbview
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
);
const
registerview
=
cbview
.
registerpanel
;
const
registerview
=
cbview
.
registerpanel
;
spyOn
(
registerview
,
'
onProviderChosen
'
).
and
.
callThrough
();
spyOn
(
registerview
,
'
onProviderChosen
'
).
and
.
callThrough
();
registerview
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
registerview
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
spyOn
(
_converse
.
connection
,
'
connect
'
);
// Open the register panel
// Open the register panel
cbview
.
el
.
querySelector
(
'
.toggle-register-login
'
).
click
();
cbview
.
el
.
querySelector
(
'
.toggle-register-login
'
).
click
();
...
@@ -75,17 +75,18 @@
...
@@ -75,17 +75,18 @@
form
.
querySelector
(
'
input[name=domain]
'
).
value
=
'
conversejs.org
'
;
form
.
querySelector
(
'
input[name=domain]
'
).
value
=
'
conversejs.org
'
;
submit_button
.
click
();
submit_button
.
click
();
expect
(
registerview
.
onProviderChosen
).
toHaveBeenCalled
();
expect
(
registerview
.
onProviderChosen
).
toHaveBeenCalled
();
expect
(
_converse
.
connection
.
connect
).
toHaveBeenCalled
(
);
await
u
.
waitUntil
(()
=>
_converse
.
connection
.
connect
.
calls
.
count
()
);
done
();
done
();
}));
}));
it
(
"
will render a registration form as received from the XMPP provider
"
,
it
(
"
will render a registration form as received from the XMPP provider
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
allow_registration
:
true
},
allow_registration
:
true
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
spyOn
(
Strophe
.
Connection
.
prototype
,
'
connect
'
);
await
u
.
waitUntil
(()
=>
_
.
get
(
_converse
.
chatboxviews
.
get
(
'
controlbox
'
),
'
registerpanel
'
));
await
u
.
waitUntil
(()
=>
_
.
get
(
_converse
.
chatboxviews
.
get
(
'
controlbox
'
),
'
registerpanel
'
));
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
const
cbview
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
);
const
cbview
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
);
...
@@ -97,7 +98,6 @@
...
@@ -97,7 +98,6 @@
spyOn
(
registerview
,
'
onRegistrationFields
'
).
and
.
callThrough
();
spyOn
(
registerview
,
'
onRegistrationFields
'
).
and
.
callThrough
();
spyOn
(
registerview
,
'
renderRegistrationForm
'
).
and
.
callThrough
();
spyOn
(
registerview
,
'
renderRegistrationForm
'
).
and
.
callThrough
();
registerview
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
registerview
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
spyOn
(
_converse
.
connection
,
'
connect
'
).
and
.
callThrough
();
expect
(
registerview
.
_registering
).
toBeFalsy
();
expect
(
registerview
.
_registering
).
toBeFalsy
();
expect
(
_converse
.
connection
.
connected
).
toBeFalsy
();
expect
(
_converse
.
connection
.
connected
).
toBeFalsy
();
...
@@ -105,7 +105,7 @@
...
@@ -105,7 +105,7 @@
registerview
.
el
.
querySelector
(
'
input[type=submit]
'
).
click
();
registerview
.
el
.
querySelector
(
'
input[type=submit]
'
).
click
();
expect
(
registerview
.
onProviderChosen
).
toHaveBeenCalled
();
expect
(
registerview
.
onProviderChosen
).
toHaveBeenCalled
();
expect
(
registerview
.
_registering
).
toBeTruthy
();
expect
(
registerview
.
_registering
).
toBeTruthy
();
expect
(
_converse
.
connection
.
connect
).
toHaveBeenCalled
(
);
await
u
.
waitUntil
(()
=>
_converse
.
connection
.
connect
.
calls
.
count
()
);
let
stanza
=
new
Strophe
.
Builder
(
"
stream:features
"
,
{
let
stanza
=
new
Strophe
.
Builder
(
"
stream:features
"
,
{
'
xmlns:stream
'
:
"
http://etherx.jabber.org/streams
"
,
'
xmlns:stream
'
:
"
http://etherx.jabber.org/streams
"
,
...
@@ -137,7 +137,7 @@
...
@@ -137,7 +137,7 @@
it
(
"
will set form_type to legacy and submit it as legacy
"
,
it
(
"
will set form_type to legacy and submit it as legacy
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
allow_registration
:
true
},
allow_registration
:
true
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
...
@@ -194,7 +194,7 @@
...
@@ -194,7 +194,7 @@
it
(
"
will set form_type to xform and submit it as xform
"
,
it
(
"
will set form_type to xform and submit it as xform
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
allow_registration
:
true
},
allow_registration
:
true
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
...
@@ -267,7 +267,7 @@
...
@@ -267,7 +267,7 @@
it
(
"
renders the account registration form
"
,
it
(
"
renders the account registration form
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
auto_login
:
false
,
{
auto_login
:
false
,
view_mode
:
'
fullscreen
'
,
view_mode
:
'
fullscreen
'
,
allow_registration
:
true
},
allow_registration
:
true
},
...
...
spec/roomslist.js
View file @
9d77a4ef
...
@@ -53,7 +53,7 @@
...
@@ -53,7 +53,7 @@
it
(
"
uses bookmarks to determine groupchat names
"
,
it
(
"
uses bookmarks to determine groupchat names
"
,
mock
.
initConverse
(
mock
.
initConverse
(
{
'
connection
'
:
[
'
send
'
]}
,
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
,
'
emojisInitialized
'
],
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
,
'
emojisInitialized
'
],
{
'
view_mode
'
:
'
fullscreen
'
},
{
'
view_mode
'
:
'
fullscreen
'
},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
...
@@ -113,7 +113,7 @@
...
@@ -113,7 +113,7 @@
describe
(
"
A groupchat shown in the groupchats list
"
,
function
()
{
describe
(
"
A groupchat shown in the groupchats list
"
,
function
()
{
it
(
"
is highlighted if its currently open
"
,
mock
.
initConverse
(
it
(
"
is highlighted if it
'
s currently open
"
,
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
,
'
emojisInitialized
'
],
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
,
'
emojisInitialized
'
],
{
view_mode
:
'
fullscreen
'
,
{
view_mode
:
'
fullscreen
'
,
allow_bookmarks
:
false
// Makes testing easier, otherwise we have to mock stanza traffic.
allow_bookmarks
:
false
// Makes testing easier, otherwise we have to mock stanza traffic.
...
@@ -137,8 +137,6 @@
...
@@ -137,8 +137,6 @@
expect
(
room_els
.
length
).
toBe
(
1
);
expect
(
room_els
.
length
).
toBe
(
1
);
item
=
room_els
[
0
];
item
=
room_els
[
0
];
expect
(
item
.
textContent
.
trim
()).
toBe
(
'
balcony@chat.shakespeare.lit
'
);
expect
(
item
.
textContent
.
trim
()).
toBe
(
'
balcony@chat.shakespeare.lit
'
);
const
conv_el
=
document
.
querySelector
(
'
#conversejs
'
);
conv_el
.
parentElement
.
removeChild
(
conv_el
);
done
();
done
();
}));
}));
...
...
spec/smacks.js
View file @
9d77a4ef
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
it
(
"
gets enabled with an <enable> stanza and resumed with a <resume> stanza
"
,
it
(
"
gets enabled with an <enable> stanza and resumed with a <resume> stanza
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
c
onnectionInitialized
'
,
'
c
hatBoxesInitialized
'
],
null
,
[
'
chatBoxesInitialized
'
],
{
'
auto_login
'
:
false
,
{
'
auto_login
'
:
false
,
'
enable_smacks
'
:
true
,
'
enable_smacks
'
:
true
,
'
show_controlbox_by_default
'
:
true
,
'
show_controlbox_by_default
'
:
true
,
...
...
src/converse-chatview.js
View file @
9d77a4ef
...
@@ -1124,7 +1124,7 @@ converse.plugins.add('converse-chatview', {
...
@@ -1124,7 +1124,7 @@ converse.plugins.add('converse-chatview', {
if
(
Backbone
.
history
.
getFragment
()
===
"
converse/chat?jid=
"
+
this
.
model
.
get
(
'
jid
'
))
{
if
(
Backbone
.
history
.
getFragment
()
===
"
converse/chat?jid=
"
+
this
.
model
.
get
(
'
jid
'
))
{
_converse
.
router
.
navigate
(
''
);
_converse
.
router
.
navigate
(
''
);
}
}
if
(
_converse
.
connection
.
connected
)
{
if
(
_converse
.
api
.
connection
.
connected
()
)
{
// Immediately sending the chat state, because the
// Immediately sending the chat state, because the
// model is going to be destroyed afterwards.
// model is going to be destroyed afterwards.
this
.
model
.
setChatState
(
_converse
.
INACTIVE
);
this
.
model
.
setChatState
(
_converse
.
INACTIVE
);
...
...
src/converse-controlbox.js
View file @
9d77a4ef
...
@@ -154,6 +154,7 @@ converse.plugins.add('converse-controlbox', {
...
@@ -154,6 +154,7 @@ converse.plugins.add('converse-controlbox', {
_converse
.
api
.
promises
.
add
(
'
controlBoxInitialized
'
);
_converse
.
api
.
promises
.
add
(
'
controlBoxInitialized
'
);
const
addControlBox
=
()
=>
_converse
.
chatboxes
.
add
({
'
id
'
:
'
controlbox
'
});
const
addControlBox
=
()
=>
_converse
.
chatboxes
.
add
({
'
id
'
:
'
controlbox
'
});
_converse
.
ControlBox
=
_converse
.
ChatBox
.
extend
({
_converse
.
ControlBox
=
_converse
.
ChatBox
.
extend
({
...
@@ -220,9 +221,9 @@ converse.plugins.add('converse-controlbox', {
...
@@ -220,9 +221,9 @@ converse.plugins.add('converse-controlbox', {
}
else
{
}
else
{
this
.
hide
();
this
.
hide
();
}
}
if
(
!
_converse
.
connection
.
connected
||
!
_converse
.
connection
.
authenticated
||
const
connection
=
get
(
_converse
,
'
connection
'
,
{});
_converse
.
connection
.
disconnecting
)
{
if
(
!
connection
.
connected
||
!
connection
.
authenticated
||
connection
.
disconnecting
)
{
this
.
renderLoginPanel
();
this
.
renderLoginPanel
();
}
else
if
(
this
.
model
.
get
(
'
connected
'
))
{
}
else
if
(
this
.
model
.
get
(
'
connected
'
))
{
this
.
renderControlBoxPane
();
this
.
renderControlBoxPane
();
...
@@ -296,7 +297,8 @@ converse.plugins.add('converse-controlbox', {
...
@@ -296,7 +297,8 @@ converse.plugins.add('converse-controlbox', {
if
(
_converse
.
sticky_controlbox
)
{
if
(
_converse
.
sticky_controlbox
)
{
return
;
return
;
}
}
if
(
_converse
.
connection
.
connected
&&
!
_converse
.
connection
.
disconnecting
)
{
const
connection
=
get
(
_converse
,
'
connection
'
,
{});
if
(
connection
.
connected
&&
!
connection
.
disconnecting
)
{
this
.
model
.
save
({
'
closed
'
:
true
});
this
.
model
.
save
({
'
closed
'
:
true
});
}
else
{
}
else
{
this
.
model
.
trigger
(
'
hide
'
);
this
.
model
.
trigger
(
'
hide
'
);
...
@@ -319,7 +321,8 @@ converse.plugins.add('converse-controlbox', {
...
@@ -319,7 +321,8 @@ converse.plugins.add('converse-controlbox', {
}
}
u
.
addClass
(
'
hidden
'
,
this
.
el
);
u
.
addClass
(
'
hidden
'
,
this
.
el
);
_converse
.
api
.
trigger
(
'
chatBoxClosed
'
,
this
);
_converse
.
api
.
trigger
(
'
chatBoxClosed
'
,
this
);
if
(
!
_converse
.
connection
.
connected
)
{
if
(
!
_converse
.
api
.
connection
.
connected
())
{
_converse
.
controlboxtoggle
.
render
();
_converse
.
controlboxtoggle
.
render
();
}
}
_converse
.
controlboxtoggle
.
show
(
callback
);
_converse
.
controlboxtoggle
.
show
(
callback
);
...
@@ -464,7 +467,7 @@ converse.plugins.add('converse-controlbox', {
...
@@ -464,7 +467,7 @@ converse.plugins.add('converse-controlbox', {
if
([
"
converse/login
"
,
"
converse/register
"
].
includes
(
Backbone
.
history
.
getFragment
()))
{
if
([
"
converse/login
"
,
"
converse/register
"
].
includes
(
Backbone
.
history
.
getFragment
()))
{
_converse
.
router
.
navigate
(
''
,
{
'
replace
'
:
true
});
_converse
.
router
.
navigate
(
''
,
{
'
replace
'
:
true
});
}
}
_converse
.
connection
.
reset
();
_converse
.
connection
&&
_converse
.
connection
.
reset
();
_converse
.
api
.
user
.
login
(
jid
,
password
);
_converse
.
api
.
user
.
login
(
jid
,
password
);
}
}
});
});
...
@@ -510,7 +513,7 @@ converse.plugins.add('converse-controlbox', {
...
@@ -510,7 +513,7 @@ converse.plugins.add('converse-controlbox', {
// artifacts (i.e. on page load the toggle is shown only to then
// artifacts (i.e. on page load the toggle is shown only to then
// seconds later be hidden in favor of the controlbox).
// seconds later be hidden in favor of the controlbox).
this
.
el
.
innerHTML
=
tpl_controlbox_toggle
({
this
.
el
.
innerHTML
=
tpl_controlbox_toggle
({
'
label_toggle
'
:
_converse
.
connection
.
connected
?
__
(
'
Chat Contacts
'
)
:
__
(
'
Toggle chat
'
)
'
label_toggle
'
:
_converse
.
api
.
connection
.
connected
()
?
__
(
'
Chat Contacts
'
)
:
__
(
'
Toggle chat
'
)
})
})
return
this
;
return
this
;
},
},
...
@@ -529,7 +532,7 @@ converse.plugins.add('converse-controlbox', {
...
@@ -529,7 +532,7 @@ converse.plugins.add('converse-controlbox', {
if
(
!
controlbox
)
{
if
(
!
controlbox
)
{
controlbox
=
addControlBox
();
controlbox
=
addControlBox
();
}
}
if
(
_converse
.
connection
.
connected
)
{
if
(
_converse
.
api
.
connection
.
connected
()
)
{
controlbox
.
save
({
'
closed
'
:
false
});
controlbox
.
save
({
'
closed
'
:
false
});
}
else
{
}
else
{
controlbox
.
trigger
(
'
show
'
);
controlbox
.
trigger
(
'
show
'
);
...
@@ -540,7 +543,7 @@ converse.plugins.add('converse-controlbox', {
...
@@ -540,7 +543,7 @@ converse.plugins.add('converse-controlbox', {
e
.
preventDefault
();
e
.
preventDefault
();
if
(
u
.
isVisible
(
_converse
.
root
.
querySelector
(
"
#controlbox
"
)))
{
if
(
u
.
isVisible
(
_converse
.
root
.
querySelector
(
"
#controlbox
"
)))
{
const
controlbox
=
_converse
.
chatboxes
.
get
(
'
controlbox
'
);
const
controlbox
=
_converse
.
chatboxes
.
get
(
'
controlbox
'
);
if
(
_converse
.
connection
.
connected
)
{
if
(
_converse
.
api
.
connection
.
connected
)
{
controlbox
.
save
({
closed
:
true
});
controlbox
.
save
({
closed
:
true
});
}
else
{
}
else
{
controlbox
.
trigger
(
'
hide
'
);
controlbox
.
trigger
(
'
hide
'
);
...
@@ -582,10 +585,9 @@ converse.plugins.add('converse-controlbox', {
...
@@ -582,10 +585,9 @@ converse.plugins.add('converse-controlbox', {
});
});
Promise
.
all
([
_converse
.
api
.
waitUntil
(
'
chatBoxViewsInitialized
'
)
_converse
.
api
.
waitUntil
(
'
connectionInitialized
'
),
.
then
(
addControlBox
)
_converse
.
api
.
waitUntil
(
'
chatBoxViewsInitialized
'
)
.
catch
(
e
=>
_converse
.
log
(
e
,
Strophe
.
LogLevel
.
FATAL
));
]).
then
(
addControlBox
).
catch
(
e
=>
_converse
.
log
(
e
,
Strophe
.
LogLevel
.
FATAL
));
_converse
.
api
.
listen
.
on
(
'
chatBoxesFetched
'
,
()
=>
{
_converse
.
api
.
listen
.
on
(
'
chatBoxesFetched
'
,
()
=>
{
const
controlbox
=
_converse
.
chatboxes
.
get
(
'
controlbox
'
)
||
addControlBox
();
const
controlbox
=
_converse
.
chatboxes
.
get
(
'
controlbox
'
)
||
addControlBox
();
...
...
src/converse-dragresize.js
View file @
9d77a4ef
...
@@ -351,7 +351,7 @@ converse.plugins.add('converse-dragresize', {
...
@@ -351,7 +351,7 @@ converse.plugins.add('converse-dragresize', {
_converse
.
resizing
.
chatbox
.
width
,
_converse
.
resizing
.
chatbox
.
width
,
_converse
.
resizing
.
chatbox
.
model
.
get
(
'
default_width
'
)
_converse
.
resizing
.
chatbox
.
model
.
get
(
'
default_width
'
)
);
);
if
(
_converse
.
connection
.
connected
)
{
if
(
_converse
.
api
.
connection
.
connected
()
)
{
_converse
.
resizing
.
chatbox
.
model
.
save
({
'
height
'
:
height
});
_converse
.
resizing
.
chatbox
.
model
.
save
({
'
height
'
:
height
});
_converse
.
resizing
.
chatbox
.
model
.
save
({
'
width
'
:
width
});
_converse
.
resizing
.
chatbox
.
model
.
save
({
'
width
'
:
width
});
}
else
{
}
else
{
...
...
src/converse-minimize.js
View file @
9d77a4ef
...
@@ -318,7 +318,7 @@ converse.plugins.add('converse-minimize', {
...
@@ -318,7 +318,7 @@ converse.plugins.add('converse-minimize', {
* @param { _converse.ChatBoxView|_converse.ChatRoomView|_converse.ControlBoxView|_converse.HeadlinesBoxView } [newchat]
* @param { _converse.ChatBoxView|_converse.ChatRoomView|_converse.ControlBoxView|_converse.HeadlinesBoxView } [newchat]
*/
*/
async
trimChats
(
newchat
)
{
async
trimChats
(
newchat
)
{
if
(
_converse
.
no_trimming
||
!
_converse
.
connection
.
connected
||
_converse
.
view_mode
!==
'
overlayed
'
)
{
if
(
_converse
.
no_trimming
||
!
_converse
.
api
.
connection
.
connected
()
||
_converse
.
view_mode
!==
'
overlayed
'
)
{
return
;
return
;
}
}
const
shown_chats
=
this
.
getShownChats
();
const
shown_chats
=
this
.
getShownChats
();
...
@@ -556,10 +556,7 @@ converse.plugins.add('converse-minimize', {
...
@@ -556,10 +556,7 @@ converse.plugins.add('converse-minimize', {
});
});
/************************ BEGIN Event Handlers ************************/
/************************ BEGIN Event Handlers ************************/
Promise
.
all
([
_converse
.
api
.
waitUntil
(
'
chatBoxViewsInitialized
'
).
then
(()
=>
{
_converse
.
api
.
waitUntil
(
'
connectionInitialized
'
),
_converse
.
api
.
waitUntil
(
'
chatBoxViewsInitialized
'
)
]).
then
(()
=>
{
_converse
.
minimized_chats
=
new
_converse
.
MinimizedChats
({
_converse
.
minimized_chats
=
new
_converse
.
MinimizedChats
({
model
:
_converse
.
chatboxes
model
:
_converse
.
chatboxes
});
});
...
...
src/converse-omemo.js
View file @
9d77a4ef
...
@@ -240,8 +240,8 @@ converse.plugins.add('converse-omemo', {
...
@@ -240,8 +240,8 @@ converse.plugins.add('converse-omemo', {
/* The initialize function gets called as soon as the plugin is
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
* loaded by Converse.js's plugin machinery.
*/
*/
const
{
_converse
}
=
this
,
const
{
_converse
}
=
this
;
{
__
}
=
_converse
;
const
{
__
}
=
_converse
;
_converse
.
api
.
settings
.
update
({
_converse
.
api
.
settings
.
update
({
'
omemo_default
'
:
false
,
'
omemo_default
'
:
false
,
...
...
src/converse-register.js
View file @
9d77a4ef
...
@@ -175,7 +175,7 @@ converse.plugins.add('converse-register', {
...
@@ -175,7 +175,7 @@ converse.plugins.add('converse-register', {
initialize
()
{
initialize
()
{
this
.
reset
();
this
.
reset
();
this
.
registerHooks
(
);
_converse
.
api
.
listen
.
on
(
'
connectionInitialized
'
,
()
=>
this
.
registerHooks
()
);
},
},
render
()
{
render
()
{
...
@@ -340,7 +340,7 @@ converse.plugins.add('converse-register', {
...
@@ -340,7 +340,7 @@ converse.plugins.add('converse-register', {
* @method _converse.RegisterPanel#fetchRegistrationForm
* @method _converse.RegisterPanel#fetchRegistrationForm
* @param { String } domain_name - XMPP server domain
* @param { String } domain_name - XMPP server domain
*/
*/
fetchRegistrationForm
(
domain_name
)
{
async
fetchRegistrationForm
(
domain_name
)
{
if
(
!
this
.
model
.
get
(
'
registration_form_rendered
'
))
{
if
(
!
this
.
model
.
get
(
'
registration_form_rendered
'
))
{
this
.
renderRegistrationRequest
();
this
.
renderRegistrationRequest
();
}
}
...
@@ -348,7 +348,8 @@ converse.plugins.add('converse-register', {
...
@@ -348,7 +348,8 @@ converse.plugins.add('converse-register', {
'
domain
'
:
Strophe
.
getDomainFromJid
(
domain_name
),
'
domain
'
:
Strophe
.
getDomainFromJid
(
domain_name
),
'
_registering
'
:
true
'
_registering
'
:
true
});
});
_converse
.
connection
.
connect
(
this
.
domain
,
""
,
this
.
onConnectStatusChanged
.
bind
(
this
));
await
_converse
.
initConnection
(
this
.
domain
);
_converse
.
connection
.
connect
(
this
.
domain
,
""
,
status
=>
this
.
onConnectStatusChanged
(
status
));
return
false
;
return
false
;
},
},
...
...
src/headless/converse-bosh.js
View file @
9d77a4ef
...
@@ -19,6 +19,10 @@ const BOSH_SESSION_ID = 'converse.bosh-session';
...
@@ -19,6 +19,10 @@ const BOSH_SESSION_ID = 'converse.bosh-session';
converse
.
plugins
.
add
(
'
converse-bosh
'
,
{
converse
.
plugins
.
add
(
'
converse-bosh
'
,
{
enabled
()
{
return
true
;
},
initialize
()
{
initialize
()
{
const
{
_converse
}
=
this
;
const
{
_converse
}
=
this
;
...
@@ -35,9 +39,15 @@ converse.plugins.add('converse-bosh', {
...
@@ -35,9 +39,15 @@ converse.plugins.add('converse-bosh', {
_converse
.
bosh_session
.
browserStorage
=
new
BrowserStorage
.
session
(
id
);
_converse
.
bosh_session
.
browserStorage
=
new
BrowserStorage
.
session
(
id
);
await
new
Promise
(
resolve
=>
_converse
.
bosh_session
.
fetch
({
'
success
'
:
resolve
,
'
error
'
:
resolve
}));
await
new
Promise
(
resolve
=>
_converse
.
bosh_session
.
fetch
({
'
success
'
:
resolve
,
'
error
'
:
resolve
}));
}
}
if
(
_converse
.
jid
&&
_converse
.
bosh_session
.
get
(
'
jid
'
)
===
_converse
.
jid
)
{
if
(
_converse
.
jid
)
{
_converse
.
bosh_session
.
clear
({
'
silent
'
:
true
});
if
(
_converse
.
bosh_session
.
get
(
'
jid
'
)
!==
_converse
.
jid
)
{
_converse
.
bosh_session
.
save
({
'
jid
'
:
_converse
.
jid
,
id
});
const
jid
=
await
_converse
.
setUserJID
(
_converse
.
jid
);
_converse
.
bosh_session
.
clear
({
'
silent
'
:
true
});
_converse
.
bosh_session
.
save
({
jid
});
}
}
else
{
// Keepalive
const
jid
=
_converse
.
bosh_session
.
get
(
'
jid
'
);
jid
&&
await
_converse
.
setUserJID
();
}
}
return
_converse
.
bosh_session
;
return
_converse
.
bosh_session
;
}
}
...
@@ -45,17 +55,17 @@ converse.plugins.add('converse-bosh', {
...
@@ -45,17 +55,17 @@ converse.plugins.add('converse-bosh', {
_converse
.
startNewPreboundBOSHSession
=
function
()
{
_converse
.
startNewPreboundBOSHSession
=
function
()
{
if
(
!
_converse
.
prebind_url
)
{
if
(
!
_converse
.
prebind_url
)
{
throw
new
Error
(
throw
new
Error
(
"
startNewPreboundBOSHSession: If you use prebind then you MUST supply a prebind_url
"
);
"
attemptPreboundSession: If you use prebind then you MUST supply a prebind_url
"
);
}
}
const
xhr
=
new
XMLHttpRequest
();
const
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
'
GET
'
,
_converse
.
prebind_url
,
true
);
xhr
.
open
(
'
GET
'
,
_converse
.
prebind_url
,
true
);
xhr
.
setRequestHeader
(
'
Accept
'
,
'
application/json, text/javascript
'
);
xhr
.
setRequestHeader
(
'
Accept
'
,
'
application/json, text/javascript
'
);
xhr
.
onload
=
function
()
{
xhr
.
onload
=
async
function
()
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
400
)
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
400
)
{
const
data
=
JSON
.
parse
(
xhr
.
responseText
);
const
data
=
JSON
.
parse
(
xhr
.
responseText
);
const
jid
=
await
_converse
.
setUserJID
(
data
.
jid
);
_converse
.
connection
.
attach
(
_converse
.
connection
.
attach
(
data
.
jid
,
jid
,
data
.
sid
,
data
.
sid
,
data
.
rid
,
data
.
rid
,
_converse
.
onConnectStatusChanged
_converse
.
onConnectStatusChanged
...
@@ -79,9 +89,6 @@ converse.plugins.add('converse-bosh', {
...
@@ -79,9 +89,6 @@ converse.plugins.add('converse-bosh', {
_converse
.
restoreBOSHSession
=
async
function
()
{
_converse
.
restoreBOSHSession
=
async
function
()
{
if
(
!
_converse
.
api
.
connection
.
isType
(
'
bosh
'
))
{
return
false
;
}
const
jid
=
(
await
initBOSHSession
()).
get
(
'
jid
'
);
const
jid
=
(
await
initBOSHSession
()).
get
(
'
jid
'
);
if
(
jid
)
{
if
(
jid
)
{
try
{
try
{
...
@@ -119,9 +126,7 @@ converse.plugins.add('converse-bosh', {
...
@@ -119,9 +126,7 @@ converse.plugins.add('converse-bosh', {
}
}
});
});
_converse
.
api
.
listen
.
on
(
'
addClientFeatures
'
,
_converse
.
api
.
listen
.
on
(
'
addClientFeatures
'
,
()
=>
_converse
.
api
.
disco
.
own
.
features
.
add
(
Strophe
.
NS
.
BOSH
));
()
=>
_converse
.
api
.
disco
.
own
.
features
.
add
(
Strophe
.
NS
.
BOSH
)
);
/************************ END Event Handlers ************************/
/************************ END Event Handlers ************************/
...
...
src/headless/converse-chatboxes.js
View file @
9d77a4ef
...
@@ -850,8 +850,8 @@ converse.plugins.add('converse-chatboxes', {
...
@@ -850,8 +850,8 @@ converse.plugins.add('converse-chatboxes', {
'
to
'
:
this
.
get
(
'
jid
'
),
'
to
'
:
this
.
get
(
'
jid
'
),
'
type
'
:
'
chat
'
'
type
'
:
'
chat
'
}).
c
(
this
.
get
(
'
chat_state
'
),
{
'
xmlns
'
:
Strophe
.
NS
.
CHATSTATES
}).
up
()
}).
c
(
this
.
get
(
'
chat_state
'
),
{
'
xmlns
'
:
Strophe
.
NS
.
CHATSTATES
}).
up
()
.
c
(
'
no-store
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
HINTS
}).
up
()
.
c
(
'
no-store
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
HINTS
}).
up
()
.
c
(
'
no-permanent-store
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
HINTS
})
.
c
(
'
no-permanent-store
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
HINTS
})
);
);
}
}
},
},
...
...
src/headless/converse-core.js
View file @
9d77a4ef
...
@@ -230,6 +230,7 @@ _converse.default_settings = {
...
@@ -230,6 +230,7 @@ _converse.default_settings = {
csi_waiting_time
:
0
,
// Support for XEP-0352. Seconds before client is considered idle and CSI is sent out.
csi_waiting_time
:
0
,
// Support for XEP-0352. Seconds before client is considered idle and CSI is sent out.
debug
:
false
,
debug
:
false
,
default_state
:
'
online
'
,
default_state
:
'
online
'
,
discover_connection_methods
:
false
,
geouri_regex
:
/https
\:\/\/
www.openstreetmap.org
\/
.*#map=
[
0-9
]
+
\/([\-
0-9.
]
+
)\/([\-
0-9.
]
+
)\S
*/g
,
geouri_regex
:
/https
\:\/\/
www.openstreetmap.org
\/
.*#map=
[
0-9
]
+
\/([\-
0-9.
]
+
)\/([\-
0-9.
]
+
)\S
*/g
,
geouri_replacement
:
'
https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2
'
,
geouri_replacement
:
'
https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2
'
,
idle_presence_timeout
:
300
,
// Seconds after which an idle presence is sent
idle_presence_timeout
:
300
,
// Seconds after which an idle presence is sent
...
@@ -330,7 +331,7 @@ function addPromise (promise) {
...
@@ -330,7 +331,7 @@ function addPromise (promise) {
}
}
_converse
.
isTestEnv
=
function
()
{
_converse
.
isTestEnv
=
function
()
{
return
_
.
get
(
_converse
.
connection
,
'
service
'
)
===
'
jasmine tests
'
;
return
Strophe
.
Connection
.
name
===
'
MockConnection
'
;
}
}
...
@@ -457,7 +458,7 @@ async function attemptNonPreboundSession (credentials, automatic) {
...
@@ -457,7 +458,7 @@ async function attemptNonPreboundSession (credentials, automatic) {
}
else
if
(
!
_converse
.
isTestEnv
()
&&
window
.
PasswordCredential
)
{
}
else
if
(
!
_converse
.
isTestEnv
()
&&
window
.
PasswordCredential
)
{
connect
(
await
getLoginCredentialsFromBrowser
());
connect
(
await
getLoginCredentialsFromBrowser
());
}
else
{
}
else
{
throw
new
Error
(
"
attemptNonPreboundSession: Could not find any credentials to log you in with!
"
);
_converse
.
log
(
"
attemptNonPreboundSession: Could not find any credentials to log in with
"
,
Strophe
.
LogLevel
.
WARN
);
}
}
}
else
if
([
_converse
.
ANONYMOUS
,
_converse
.
EXTERNAL
].
includes
(
_converse
.
authentication
)
&&
(
!
automatic
||
_converse
.
auto_login
))
{
}
else
if
([
_converse
.
ANONYMOUS
,
_converse
.
EXTERNAL
].
includes
(
_converse
.
authentication
)
&&
(
!
automatic
||
_converse
.
auto_login
))
{
connect
();
connect
();
...
@@ -523,9 +524,7 @@ function reconnect () {
...
@@ -523,9 +524,7 @@ function reconnect () {
const
debouncedReconnect
=
_
.
debounce
(
reconnect
,
2000
);
const
debouncedReconnect
=
_
.
debounce
(
reconnect
,
2000
);
_converse
.
shouldClearCache
=
function
()
{
_converse
.
shouldClearCache
=
()
=>
(
!
_converse
.
config
.
get
(
'
trusted
'
)
||
_converse
.
isTestEnv
());
return
!
_converse
.
config
.
get
(
'
trusted
'
)
||
_converse
.
isTestEnv
();
}
function
clearSession
()
{
function
clearSession
()
{
if
(
_converse
.
session
!==
undefined
)
{
if
(
_converse
.
session
!==
undefined
)
{
...
@@ -548,37 +547,84 @@ function clearSession () {
...
@@ -548,37 +547,84 @@ function clearSession () {
}
}
/**
async
function
onDomainDiscovered
(
response
)
{
* Creates a new Strophe.Connection instance and if applicable, attempt to
const
text
=
await
response
.
text
();
* restore the BOSH session or if `auto_login` is true, attempt to log in.
const
xrd
=
(
new
window
.
DOMParser
()).
parseFromString
(
text
,
"
text/xml
"
).
firstElementChild
;
if
(
xrd
.
nodeName
!=
"
XRD
"
||
xrd
.
namespaceURI
!=
"
http://docs.oasis-open.org/ns/xri/xrd-1.0
"
)
{
return
_converse
.
log
(
"
Could not discover XEP-0156 connection methods
"
,
Strophe
.
LogLevel
.
WARN
);
}
const
bosh_links
=
sizzle
(
`Link[rel="urn:xmpp:alt-connections:xbosh"]`
,
xrd
);
const
ws_links
=
sizzle
(
`Link[rel="urn:xmpp:alt-connections:websocket"]`
,
xrd
);
const
bosh_methods
=
bosh_links
.
map
(
el
=>
el
.
getAttribute
(
'
href
'
));
const
ws_methods
=
ws_links
.
map
(
el
=>
el
.
getAttribute
(
'
href
'
));
// TODO: support multiple endpoints
_converse
.
websocket_url
=
ws_methods
.
pop
();
_converse
.
bosh_service_url
=
bosh_methods
.
pop
();
if
(
bosh_methods
.
length
===
0
&&
ws_methods
.
length
===
0
)
{
_converse
.
log
(
"
onDomainDiscovered: neither BOSH nor WebSocket connection methods have been specified with XEP-0156.
"
,
Strophe
.
LogLevel
.
WARN
);
}
}
/* Use XEP-0156 to check whether this host advertises websocket or BOSH connection methods.
*/
*/
_converse
.
initConnection
=
async
function
()
{
async
function
discoverConnectionMethods
(
domain
)
{
if
(
!
_converse
.
connection
)
{
const
options
=
{
if
(
!
_converse
.
bosh_service_url
&&
!
_converse
.
websocket_url
)
{
'
mode
'
:
'
cors
'
,
throw
new
Error
(
"
initConnection: you must supply a value for either the bosh_service_url or websocket_url or both.
"
);
'
headers
'
:
{
'
Accept
'
:
'
application/xrd+xml, text/xml
'
}
}
if
((
'
WebSocket
'
in
window
||
'
MozWebSocket
'
in
window
)
&&
_converse
.
websocket_url
)
{
};
_converse
.
connection
=
new
Strophe
.
Connection
(
const
url
=
`https://
${
domain
}
/.well-known/host-meta`
;
_converse
.
websocket_url
,
let
response
;
Object
.
assign
(
_converse
.
default_connection_options
,
_converse
.
connection_options
)
try
{
);
response
=
await
fetch
(
url
,
options
);
}
else
if
(
_converse
.
bosh_service_url
)
{
}
catch
(
e
)
{
_converse
.
connection
=
new
Strophe
.
Connection
(
_converse
.
log
(
`Failed to discover alternative connection methods at
${
url
}
`
,
Strophe
.
LogLevel
.
ERROR
);
_converse
.
bosh_service_url
,
return
_converse
.
log
(
e
,
Strophe
.
LogLevel
.
ERROR
);
Object
.
assign
(
}
_converse
.
default_connection_options
,
if
(
response
.
status
>=
200
&&
response
.
status
<
400
)
{
_converse
.
connection_options
,
await
onDomainDiscovered
(
response
);
{
'
keepalive
'
:
_converse
.
keepalive
}
}
else
{
)
_converse
.
log
(
"
Could not discover XEP-0156 connection methods
"
,
Strophe
.
LogLevel
.
WARN
);
);
}
}
else
{
}
throw
new
Error
(
"
initConnection: this browser does not support
"
+
"
websockets and bosh_service_url wasn't specified.
"
);
_converse
.
initConnection
=
async
function
(
domain
)
{
if
(
_converse
.
discover_connection_methods
)
{
await
discoverConnectionMethods
(
domain
);
}
if
(
!
_converse
.
bosh_service_url
)
{
if
(
_converse
.
authentication
===
_converse
.
PREBIND
)
{
throw
new
Error
(
"
authentication is set to 'prebind' but we don't have a BOSH connection
"
);
}
}
if
(
_converse
.
auto_login
||
_converse
.
keepalive
)
{
if
(
!
_converse
.
websocket_url
)
{
await
_converse
.
api
.
user
.
login
(
null
,
null
,
true
);
throw
new
Error
(
"
initConnection: you must supply a value for either the bosh_service_url or websocket_url or both.
"
);
}
}
}
}
if
((
'
WebSocket
'
in
window
||
'
MozWebSocket
'
in
window
)
&&
_converse
.
websocket_url
)
{
_converse
.
connection
=
new
Strophe
.
Connection
(
_converse
.
websocket_url
,
Object
.
assign
(
_converse
.
default_connection_options
,
_converse
.
connection_options
)
);
}
else
if
(
_converse
.
bosh_service_url
)
{
_converse
.
connection
=
new
Strophe
.
Connection
(
_converse
.
bosh_service_url
,
Object
.
assign
(
_converse
.
default_connection_options
,
_converse
.
connection_options
,
{
'
keepalive
'
:
_converse
.
keepalive
}
)
);
}
else
{
throw
new
Error
(
"
initConnection: this browser does not support
"
+
"
websockets and bosh_service_url wasn't specified.
"
);
}
setUpXMLLogging
();
setUpXMLLogging
();
/**
/**
* Triggered once the `Strophe.Connection` constructor has been initialized, which
* Triggered once the `Strophe.Connection` constructor has been initialized, which
...
@@ -587,10 +633,10 @@ _converse.initConnection = async function () {
...
@@ -587,10 +633,10 @@ _converse.initConnection = async function () {
* @event _converse#connectionInitialized
* @event _converse#connectionInitialized
*/
*/
_converse
.
api
.
trigger
(
'
connectionInitialized
'
);
_converse
.
api
.
trigger
(
'
connectionInitialized
'
);
}
;
}
async
function
setUserJID
(
jid
)
{
async
function
initSession
(
jid
)
{
const
bare_jid
=
Strophe
.
getBareJidFromJid
(
jid
).
toLowerCase
();
const
bare_jid
=
Strophe
.
getBareJidFromJid
(
jid
).
toLowerCase
();
const
id
=
`converse.session-
${
bare_jid
}
`
;
const
id
=
`converse.session-
${
bare_jid
}
`
;
if
(
!
_converse
.
session
||
_converse
.
session
.
get
(
'
id
'
)
!==
id
)
{
if
(
!
_converse
.
session
||
_converse
.
session
.
get
(
'
id
'
)
!==
id
)
{
...
@@ -612,23 +658,14 @@ async function setUserJID (jid) {
...
@@ -612,23 +658,14 @@ async function setUserJID (jid) {
}
else
{
}
else
{
saveJIDtoSession
(
jid
);
saveJIDtoSession
(
jid
);
}
}
/**
* Triggered whenever the user's JID has been updated
* @event _converse#setUserJID
*/
_converse
.
api
.
trigger
(
'
setUserJID
'
);
return
jid
;
}
}
function
saveJIDtoSession
(
jid
)
{
function
saveJIDtoSession
(
jid
)
{
jid
=
_converse
.
session
.
get
(
'
jid
'
)
||
jid
;
jid
=
_converse
.
session
.
get
(
'
jid
'
)
||
jid
;
if
(
_converse
.
authentication
!==
_converse
.
ANONYMOUS
&&
!
Strophe
.
getResourceFromJid
(
jid
))
{
if
(
_converse
.
authentication
!==
_converse
.
ANONYMOUS
&&
!
Strophe
.
getResourceFromJid
(
jid
))
{
jid
=
jid
.
toLowerCase
()
+
_converse
.
generateResource
();
jid
=
jid
.
toLowerCase
()
+
_converse
.
generateResource
();
}
}
// Set JID on the connection object so that when we call
// `connection.bind` the new resource is found by Strophe.js
// and sent to the XMPP server.
_converse
.
connection
.
jid
=
jid
;
_converse
.
jid
=
jid
;
_converse
.
jid
=
jid
;
_converse
.
bare_jid
=
Strophe
.
getBareJidFromJid
(
jid
);
_converse
.
bare_jid
=
Strophe
.
getBareJidFromJid
(
jid
);
_converse
.
resource
=
Strophe
.
getResourceFromJid
(
jid
);
_converse
.
resource
=
Strophe
.
getResourceFromJid
(
jid
);
...
@@ -640,6 +677,37 @@ function saveJIDtoSession (jid) {
...
@@ -640,6 +677,37 @@ function saveJIDtoSession (jid) {
'
domain
'
:
_converse
.
domain
,
'
domain
'
:
_converse
.
domain
,
'
active
'
:
true
'
active
'
:
true
});
});
// Set JID on the connection object so that when we call `connection.bind`
// the new resource is found by Strophe.js and sent to the XMPP server.
_converse
.
connection
.
jid
=
jid
;
}
/**
* Stores the passed in JID for the current user, potentially creating a
* resource if the JID is bare.
*
* Given that we can only create an XMPP connection if we know the domain of
* the server connect to and we only know this once we know the JID, we also
* call {@link _converse.initConnection } (if necessary) to make sure that the
* connection is set up.
*
* @method _converse#setUserJID
* @emits _converse#setUserJID
* @params { String } jid
*/
_converse
.
setUserJID
=
async
function
(
jid
)
{
if
(
!
_converse
.
connection
||
!
u
.
isSameDomain
(
_converse
.
connection
.
jid
,
jid
))
{
const
domain
=
Strophe
.
getDomainFromJid
(
jid
)
await
_converse
.
initConnection
(
domain
);
}
await
initSession
(
jid
);
/**
* Triggered whenever the user's JID has been updated
* @event _converse#setUserJID
*/
_converse
.
api
.
trigger
(
'
setUserJID
'
);
return
jid
;
}
}
...
@@ -649,7 +717,7 @@ async function onConnected (reconnecting) {
...
@@ -649,7 +717,7 @@ async function onConnected (reconnecting) {
*/
*/
delete
_converse
.
connection
.
reconnecting
;
delete
_converse
.
connection
.
reconnecting
;
_converse
.
connection
.
flush
();
// Solves problem of returned PubSub BOSH response not received by browser
_converse
.
connection
.
flush
();
// Solves problem of returned PubSub BOSH response not received by browser
await
setUserJID
(
_converse
.
connection
.
jid
);
await
_converse
.
setUserJID
(
_converse
.
connection
.
jid
);
/**
/**
* Synchronous event triggered after we've sent an IQ to bind the
* Synchronous event triggered after we've sent an IQ to bind the
* user's JID resource for this session.
* user's JID resource for this session.
...
@@ -681,9 +749,9 @@ function setUpXMLLogging () {
...
@@ -681,9 +749,9 @@ function setUpXMLLogging () {
async
function
finishInitialization
()
{
async
function
finishInitialization
()
{
initClientConfig
();
initClientConfig
();
initPlugins
();
initPlugins
();
await
_converse
.
initConnection
();
_converse
.
registerGlobalEventHandlers
();
_converse
.
registerGlobalEventHandlers
();
if
(
!
Backbone
.
history
.
started
)
{
if
(
!
Backbone
.
History
.
started
)
{
Backbone
.
history
.
start
();
Backbone
.
history
.
start
();
}
}
if
(
_converse
.
idle_presence_timeout
>
0
)
{
if
(
_converse
.
idle_presence_timeout
>
0
)
{
...
@@ -691,6 +759,10 @@ async function finishInitialization () {
...
@@ -691,6 +759,10 @@ async function finishInitialization () {
_converse
.
api
.
disco
.
own
.
features
.
add
(
Strophe
.
NS
.
IDLE
);
_converse
.
api
.
disco
.
own
.
features
.
add
(
Strophe
.
NS
.
IDLE
);
});
});
}
}
if
(
_converse
.
auto_login
||
_converse
.
keepalive
&&
_
.
invoke
(
_converse
.
pluggable
.
plugins
[
'
converse-bosh
'
],
'
enabled
'
))
{
await
_converse
.
api
.
user
.
login
(
null
,
null
,
true
);
}
}
}
...
@@ -706,6 +778,7 @@ function finishDisconnection () {
...
@@ -706,6 +778,7 @@ function finishDisconnection () {
_converse
.
connection
.
reset
();
_converse
.
connection
.
reset
();
tearDown
();
tearDown
();
clearSession
();
clearSession
();
delete
_converse
.
connection
;
/**
/**
* Triggered after converse.js has disconnected from the XMPP server.
* Triggered after converse.js has disconnected from the XMPP server.
* @event _converse#disconnected
* @event _converse#disconnected
...
@@ -725,7 +798,7 @@ function fetchLoginCredentials (wait=0) {
...
@@ -725,7 +798,7 @@ function fetchLoginCredentials (wait=0) {
xhr
.
onload
=
()
=>
{
xhr
.
onload
=
()
=>
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
400
)
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
400
)
{
const
data
=
JSON
.
parse
(
xhr
.
responseText
);
const
data
=
JSON
.
parse
(
xhr
.
responseText
);
setUserJID
(
data
.
jid
).
then
(()
=>
{
_converse
.
setUserJID
(
data
.
jid
).
then
(()
=>
{
resolve
({
resolve
({
jid
:
data
.
jid
,
jid
:
data
.
jid
,
password
:
data
.
password
password
:
data
.
password
...
@@ -761,7 +834,7 @@ async function getLoginCredentials () {
...
@@ -761,7 +834,7 @@ async function getLoginCredentials () {
async
function
getLoginCredentialsFromBrowser
()
{
async
function
getLoginCredentialsFromBrowser
()
{
const
creds
=
await
navigator
.
credentials
.
get
({
'
password
'
:
true
});
const
creds
=
await
navigator
.
credentials
.
get
({
'
password
'
:
true
});
if
(
creds
&&
creds
.
type
==
'
password
'
&&
u
.
isValidJID
(
creds
.
id
))
{
if
(
creds
&&
creds
.
type
==
'
password
'
&&
u
.
isValidJID
(
creds
.
id
))
{
await
setUserJID
(
creds
.
id
);
await
_converse
.
setUserJID
(
creds
.
id
);
return
{
'
jid
'
:
creds
.
id
,
'
password
'
:
creds
.
password
};
return
{
'
jid
'
:
creds
.
id
,
'
password
'
:
creds
.
password
};
}
}
}
}
...
@@ -782,18 +855,20 @@ function cleanup () {
...
@@ -782,18 +855,20 @@ function cleanup () {
if
(
_converse
.
chatboxviews
)
{
if
(
_converse
.
chatboxviews
)
{
delete
_converse
.
chatboxviews
;
delete
_converse
.
chatboxviews
;
}
}
if
(
_converse
.
connection
)
{
_converse
.
connection
.
reset
();
}
_converse
.
stopListening
();
_converse
.
stopListening
();
_converse
.
off
();
_converse
.
off
();
}
}
_converse
.
initialize
=
async
function
(
settings
,
callback
)
{
_converse
.
initialize
=
async
function
(
settings
,
callback
)
{
cleanup
();
settings
=
settings
!==
undefined
?
settings
:
{};
settings
=
settings
!==
undefined
?
settings
:
{};
const
init_promise
=
u
.
getResolveablePromise
();
const
init_promise
=
u
.
getResolveablePromise
();
PROMISES
.
forEach
(
addPromise
);
PROMISES
.
forEach
(
addPromise
);
if
(
_converse
.
connection
!==
undefined
)
{
cleanup
();
}
if
(
'
onpagehide
'
in
window
)
{
if
(
'
onpagehide
'
in
window
)
{
// Pagehide gets thrown in more cases than unload. Specifically it
// Pagehide gets thrown in more cases than unload. Specifically it
...
@@ -877,7 +952,7 @@ _converse.initialize = async function (settings, callback) {
...
@@ -877,7 +952,7 @@ _converse.initialize = async function (settings, callback) {
if
(
_converse
.
idle_seconds
>
0
)
{
if
(
_converse
.
idle_seconds
>
0
)
{
_converse
.
idle_seconds
=
0
;
_converse
.
idle_seconds
=
0
;
}
}
if
(
!
_
converse
.
connection
.
authenticated
)
{
if
(
!
_
.
get
(
_converse
.
connection
,
'
authenticated
'
)
)
{
// We can't send out any stanzas when there's no authenticated connection.
// We can't send out any stanzas when there's no authenticated connection.
// This can happen when the connection reconnects.
// This can happen when the connection reconnects.
return
;
return
;
...
@@ -901,7 +976,7 @@ _converse.initialize = async function (settings, callback) {
...
@@ -901,7 +976,7 @@ _converse.initialize = async function (settings, callback) {
/* An interval handler running every second.
/* An interval handler running every second.
* Used for CSI and the auto_away and auto_xa features.
* Used for CSI and the auto_away and auto_xa features.
*/
*/
if
(
!
_
converse
.
connection
.
authenticated
)
{
if
(
!
_
.
get
(
_converse
.
connection
,
'
authenticated
'
)
)
{
// We can't send out any stanzas when there's no authenticated connection.
// We can't send out any stanzas when there's no authenticated connection.
// This can happen when the connection reconnects.
// This can happen when the connection reconnects.
return
;
return
;
...
@@ -1378,7 +1453,7 @@ _converse.api = {
...
@@ -1378,7 +1453,7 @@ _converse.api = {
* @returns {boolean} Whether there is an established connection or not.
* @returns {boolean} Whether there is an established connection or not.
*/
*/
connected
()
{
connected
()
{
return
(
_converse
.
connection
&&
_converse
.
connection
.
connected
)
||
fals
e
;
return
_
.
get
(
_converse
,
'
connection
'
,
{}).
connected
&&
tru
e
;
},
},
/**
/**
...
@@ -1417,7 +1492,7 @@ _converse.api = {
...
@@ -1417,7 +1492,7 @@ _converse.api = {
// We also call `_proto._doDisconnect` so that connection event handlers
// We also call `_proto._doDisconnect` so that connection event handlers
// for the old transport are removed.
// for the old transport are removed.
if
(
_converse
.
api
.
connection
.
isType
(
'
websocket
'
)
&&
_converse
.
bosh_service_url
)
{
if
(
_converse
.
api
.
connection
.
isType
(
'
websocket
'
)
&&
_converse
.
bosh_service_url
)
{
await
setUserJID
(
_converse
.
bare_jid
);
await
_converse
.
setUserJID
(
_converse
.
bare_jid
);
_converse
.
connection
.
_proto
.
_doDisconnect
();
_converse
.
connection
.
_proto
.
_doDisconnect
();
_converse
.
connection
.
_proto
=
new
Strophe
.
Bosh
(
_converse
.
connection
);
_converse
.
connection
.
_proto
=
new
Strophe
.
Bosh
(
_converse
.
connection
);
_converse
.
connection
.
service
=
_converse
.
bosh_service_url
;
_converse
.
connection
.
service
=
_converse
.
bosh_service_url
;
...
@@ -1426,9 +1501,9 @@ _converse.api = {
...
@@ -1426,9 +1501,9 @@ _converse.api = {
// When reconnecting anonymously, we need to connect with only
// When reconnecting anonymously, we need to connect with only
// the domain, not the full JID that we had in our previous
// the domain, not the full JID that we had in our previous
// (now failed) session.
// (now failed) session.
await
setUserJID
(
_converse
.
settings
.
jid
);
await
_converse
.
setUserJID
(
_converse
.
settings
.
jid
);
}
else
{
}
else
{
await
setUserJID
(
_converse
.
bare_jid
);
await
_converse
.
setUserJID
(
_converse
.
bare_jid
);
}
}
_converse
.
connection
.
_proto
.
_doDisconnect
();
_converse
.
connection
.
_proto
.
_doDisconnect
();
_converse
.
connection
.
_proto
=
new
Strophe
.
Websocket
(
_converse
.
connection
);
_converse
.
connection
.
_proto
=
new
Strophe
.
Websocket
(
_converse
.
connection
);
...
@@ -1439,7 +1514,7 @@ _converse.api = {
...
@@ -1439,7 +1514,7 @@ _converse.api = {
// When reconnecting anonymously, we need to connect with only
// When reconnecting anonymously, we need to connect with only
// the domain, not the full JID that we had in our previous
// the domain, not the full JID that we had in our previous
// (now failed) session.
// (now failed) session.
await
setUserJID
(
_converse
.
settings
.
jid
);
await
_converse
.
setUserJID
(
_converse
.
settings
.
jid
);
}
}
if
(
_converse
.
connection
.
reconnecting
)
{
if
(
_converse
.
connection
.
reconnecting
)
{
debouncedReconnect
();
debouncedReconnect
();
...
@@ -1527,20 +1602,19 @@ _converse.api = {
...
@@ -1527,20 +1602,19 @@ _converse.api = {
* fails to restore a previous auth'd session.
* fails to restore a previous auth'd session.
*/
*/
async
login
(
jid
,
password
,
automatic
=
false
)
{
async
login
(
jid
,
password
,
automatic
=
false
)
{
if
(
_converse
.
api
.
connection
.
isType
(
'
bosh
'
))
{
if
(
jid
||
_converse
.
jid
)
{
jid
=
await
_converse
.
setUserJID
(
jid
||
_converse
.
jid
);
}
// See whether there is a BOSH session to re-attach to
if
(
_
.
invoke
(
_converse
.
pluggable
.
plugins
[
'
converse-bosh
'
],
'
enabled
'
))
{
if
(
await
_converse
.
restoreBOSHSession
())
{
if
(
await
_converse
.
restoreBOSHSession
())
{
return
;
return
;
}
else
if
(
_converse
.
authentication
===
_converse
.
PREBIND
&&
(
!
automatic
||
_converse
.
auto_login
))
{
}
else
if
(
_converse
.
authentication
===
_converse
.
PREBIND
&&
(
!
automatic
||
_converse
.
auto_login
))
{
return
_converse
.
startNewPreboundBOSHSession
();
return
_converse
.
startNewPreboundBOSHSession
();
}
}
}
else
if
(
_converse
.
authentication
===
_converse
.
PREBIND
)
{
throw
new
Error
(
"
authentication is set to 'prebind' but we don't have a BOSH connection
"
);
}
}
if
(
jid
||
_converse
.
jid
)
{
// Reassign because we might have gained a resource
jid
=
await
setUserJID
(
jid
||
_converse
.
jid
);
}
password
=
password
||
_converse
.
password
;
password
=
password
||
_converse
.
password
;
const
credentials
=
(
jid
&&
password
)
?
{
jid
,
password
}
:
null
;
const
credentials
=
(
jid
&&
password
)
?
{
jid
,
password
}
:
null
;
attemptNonPreboundSession
(
credentials
,
automatic
);
attemptNonPreboundSession
(
credentials
,
automatic
);
...
@@ -1866,6 +1940,11 @@ _converse.api = {
...
@@ -1866,6 +1940,11 @@ _converse.api = {
* _converse.api.send(msg);
* _converse.api.send(msg);
*/
*/
send
(
stanza
)
{
send
(
stanza
)
{
if
(
!
_converse
.
api
.
connection
.
connected
())
{
_converse
.
log
(
"
Not sending stanza because we're not connected!
"
,
Strophe
.
LogLevel
.
WARN
);
_converse
.
log
(
Strophe
.
serialize
(
stanza
),
Strophe
.
LogLevel
.
WARN
);
return
;
}
if
(
_
.
isString
(
stanza
))
{
if
(
_
.
isString
(
stanza
))
{
stanza
=
u
.
toStanza
(
stanza
);
stanza
=
u
.
toStanza
(
stanza
);
}
}
...
...
src/headless/converse-muc.js
View file @
9d77a4ef
...
@@ -633,7 +633,7 @@ converse.plugins.add('converse-muc', {
...
@@ -633,7 +633,7 @@ converse.plugins.add('converse-muc', {
disco_entity
.
destroy
();
disco_entity
.
destroy
();
}
}
}
}
if
(
_converse
.
connection
.
connected
)
{
if
(
_converse
.
api
.
connection
.
connected
()
)
{
this
.
sendUnavailablePresence
(
exit_msg
);
this
.
sendUnavailablePresence
(
exit_msg
);
}
}
u
.
safeSave
(
this
,
{
'
connection_status
'
:
converse
.
ROOMSTATUS
.
DISCONNECTED
});
u
.
safeSave
(
this
,
{
'
connection_status
'
:
converse
.
ROOMSTATUS
.
DISCONNECTED
});
...
...
src/headless/utils/core.js
View file @
9d77a4ef
...
@@ -107,6 +107,15 @@ u.isSameBareJID = function (jid1, jid2) {
...
@@ -107,6 +107,15 @@ u.isSameBareJID = function (jid1, jid2) {
Strophe
.
getBareJidFromJid
(
jid2
).
toLowerCase
();
Strophe
.
getBareJidFromJid
(
jid2
).
toLowerCase
();
};
};
u
.
isSameDomain
=
function
(
jid1
,
jid2
)
{
if
(
!
_
.
isString
(
jid1
)
||
!
_
.
isString
(
jid2
))
{
return
false
;
}
return
Strophe
.
getDomainFromJid
(
jid1
).
toLowerCase
()
===
Strophe
.
getDomainFromJid
(
jid2
).
toLowerCase
();
};
u
.
isNewMessage
=
function
(
message
)
{
u
.
isNewMessage
=
function
(
message
)
{
/* Given a stanza, determine whether it's a new
/* Given a stanza, determine whether it's a new
* message, i.e. not a MAM archived one.
* message, i.e. not a MAM archived one.
...
...
tests/mock.js
View file @
9d77a4ef
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
const
Strophe
=
converse
.
env
.
Strophe
;
const
Strophe
=
converse
.
env
.
Strophe
;
const
dayjs
=
converse
.
env
.
dayjs
;
const
dayjs
=
converse
.
env
.
dayjs
;
const
$iq
=
converse
.
env
.
$iq
;
const
$iq
=
converse
.
env
.
$iq
;
const
u
=
converse
.
env
.
utils
;
window
.
libsignal
=
{
window
.
libsignal
=
{
'
SignalProtocolAddress
'
:
function
(
name
,
device_id
)
{
'
SignalProtocolAddress
'
:
function
(
name
,
device_id
)
{
...
@@ -32,7 +31,7 @@
...
@@ -32,7 +31,7 @@
return
Promise
.
resolve
(
key_and_tag
);
return
Promise
.
resolve
(
key_and_tag
);
}
}
},
},
'
SessionBuilder
'
:
function
(
storage
,
remote_address
)
{
'
SessionBuilder
'
:
function
(
storage
,
remote_address
)
{
// eslint-disable-line no-unused-vars
this
.
processPreKey
=
function
()
{
this
.
processPreKey
=
function
()
{
return
Promise
.
resolve
();
return
Promise
.
resolve
();
}
}
...
@@ -116,95 +115,87 @@
...
@@ -116,95 +115,87 @@
'
preventDefault
'
:
function
()
{}
'
preventDefault
'
:
function
()
{}
};
};
mock
.
mock_connection
=
function
()
{
// eslint-disable-line wrap-iife
return
function
()
{
Strophe
.
Bosh
.
prototype
.
_processRequest
=
function
()
{};
// Don't attempt to send out stanzas
const
c
=
new
Strophe
.
Connection
(
'
jasmine tests
'
);
const
sendIQ
=
c
.
sendIQ
;
c
.
IQ_stanzas
=
[];
const
OriginalConnection
=
Strophe
.
Connection
;
c
.
IQ_ids
=
[];
c
.
sendIQ
=
function
(
iq
,
callback
,
errback
)
{
function
MockConnection
(
service
,
options
)
{
if
(
!
_
.
isElement
(
iq
))
{
OriginalConnection
.
call
(
this
,
service
,
options
);
iq
=
iq
.
nodeTree
;
}
Strophe
.
Bosh
.
prototype
.
_processRequest
=
function
()
{};
// Don't attempt to send out stanzas
this
.
IQ_stanzas
.
push
(
iq
);
const
sendIQ
=
this
.
sendIQ
;
const
id
=
sendIQ
.
bind
(
this
)(
iq
,
callback
,
errback
);
this
.
IQ_ids
.
push
(
id
);
this
.
IQ_stanzas
=
[];
return
id
;
this
.
IQ_ids
=
[];
this
.
sendIQ
=
function
(
iq
,
callback
,
errback
)
{
if
(
!
_
.
isElement
(
iq
))
{
iq
=
iq
.
nodeTree
;
}
}
this
.
IQ_stanzas
.
push
(
iq
);
const
id
=
sendIQ
.
bind
(
this
)(
iq
,
callback
,
errback
);
this
.
IQ_ids
.
push
(
id
);
return
id
;
}
const
send
=
c
.
send
;
const
send
=
this
.
send
;
c
.
sent_stanzas
=
[];
this
.
sent_stanzas
=
[];
c
.
send
=
function
(
stanza
)
{
this
.
send
=
function
(
stanza
)
{
if
(
_
.
isElement
(
stanza
))
{
if
(
_
.
isElement
(
stanza
))
{
this
.
sent_stanzas
.
push
(
stanza
);
this
.
sent_stanzas
.
push
(
stanza
);
}
else
{
}
else
{
this
.
sent_stanzas
.
push
(
stanza
.
nodeTree
);
this
.
sent_stanzas
.
push
(
stanza
.
nodeTree
);
}
return
send
.
apply
(
this
,
arguments
);
}
}
return
send
.
apply
(
this
,
arguments
);
}
c
.
features
=
Strophe
.
xmlHtmlNode
(
this
.
features
=
Strophe
.
xmlHtmlNode
(
'
<stream:features xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
'
+
'
<stream:features xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
'
+
'
<ver xmlns="urn:xmpp:features:rosterver"/>
'
+
'
<ver xmlns="urn:xmpp:features:rosterver"/>
'
+
'
<csi xmlns="urn:xmpp:csi:0"/>
'
+
'
<csi xmlns="urn:xmpp:csi:0"/>
'
+
'
<c
xmlns="http://jabber.org/protocol/caps" ver="UwBpfJpEt3IoLYfWma/o/p3FFRo=" hash="sha-1" node="http://prosody.im"/>
'
+
'
<this
xmlns="http://jabber.org/protocol/caps" ver="UwBpfJpEt3IoLYfWma/o/p3FFRo=" hash="sha-1" node="http://prosody.im"/>
'
+
'
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
'
+
'
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
'
+
'
<required/>
'
+
'
<required/>
'
+
'
</bind>
'
+
'
</bind>
'
+
`<sm xmlns='urn:xmpp:sm:3'/>`
+
`<sm xmlns='urn:xmpp:sm:3'/>`
+
'
<session xmlns="urn:ietf:params:xml:ns:xmpp-session">
'
+
'
<session xmlns="urn:ietf:params:xml:ns:xmpp-session">
'
+
'
<optional/>
'
+
'
<optional/>
'
+
'
</session>
'
+
'
</session>
'
+
'
</stream:features>
'
).
firstChild
;
'
</stream:features>
'
).
firstChild
;
c
.
_proto
.
_connect
=
function
()
{
this
.
_proto
.
_connect
=
()
=>
{
c
.
connected
=
true
;
this
.
connected
=
true
;
c
.
mock
=
true
;
this
.
mock
=
true
;
c
.
jid
=
'
romeo@montague.lit/orchard
'
;
this
.
jid
=
'
romeo@montague.lit/orchard
'
;
c
.
_changeConnectStatus
(
Strophe
.
Status
.
BINDREQUIRED
);
this
.
_changeConnectStatus
(
Strophe
.
Status
.
BINDREQUIRED
);
};
};
c
.
bind
=
function
()
{
this
.
bind
=
()
=>
{
c
.
authenticated
=
true
;
this
.
authenticated
=
true
;
this
.
authenticated
=
true
;
this
.
authenticated
=
true
;
c
.
_changeConnectStatus
(
Strophe
.
Status
.
CONNECTED
);
this
.
_changeConnectStatus
(
Strophe
.
Status
.
CONNECTED
);
};
};
c
.
_proto
.
_disconnect
=
function
()
{
this
.
_proto
.
_disconnect
=
()
=>
this
.
_onDisconnectTimeout
();
c
.
_onDisconnectTimeout
()
;
this
.
_proto
.
_onDisconnectTimeout
=
_
.
noop
;
}
}
c
.
_proto
.
_onDisconnectTimeout
=
_
.
noop
;
MockConnection
.
prototype
=
Object
.
create
(
OriginalConnection
.
prototype
);
return
c
;
Strophe
.
Connection
=
MockConnection
;
};
}();
async
function
initConverse
(
settings
,
spies
=
{},
promises
)
{
async
function
initConverse
(
settings
,
spies
=
{})
{
window
.
localStorage
.
clear
();
window
.
localStorage
.
clear
();
window
.
sessionStorage
.
clear
();
window
.
sessionStorage
.
clear
();
const
el
=
document
.
querySelector
(
'
#conversejs
'
);
if
(
el
)
{
el
.
parentElement
.
removeChild
(
el
);
}
const
connection
=
mock
.
mock_connection
();
if
(
spies
&&
spies
.
connection
)
{
spies
.
connection
.
forEach
(
method
=>
spyOn
(
connection
,
method
));
}
const
_converse
=
await
converse
.
initialize
(
Object
.
assign
({
const
_converse
=
await
converse
.
initialize
(
Object
.
assign
({
'
i18n
'
:
'
en
'
,
'
animate
'
:
false
,
'
auto_subscribe
'
:
false
,
'
auto_subscribe
'
:
false
,
'
play_sounds
'
:
false
,
'
bosh_service_url
'
:
'
montague.lit/http-bind
'
,
'
bosh_service_url
'
:
'
montague.lit/http-bind
'
,
'
connection
'
:
connection
,
'
debug
'
:
false
,
'
animate
'
:
false
,
'
i18n
'
:
'
en
'
,
'
use_emojione
'
:
false
,
'
no_trimming
'
:
true
,
'
no_trimming
'
:
true
,
'
play_sounds
'
:
false
,
'
use_emojione
'
:
false
,
'
view_mode
'
:
mock
.
view_mode
,
'
view_mode
'
:
mock
.
view_mode
,
'
debug
'
:
false
},
settings
||
{}));
},
settings
||
{}));
if
(
spies
&&
spies
.
_converse
)
{
if
(
spies
&&
spies
.
_converse
)
{
...
@@ -214,7 +205,7 @@
...
@@ -214,7 +205,7 @@
_converse
.
ChatBoxViews
.
prototype
.
trimChat
=
function
()
{};
_converse
.
ChatBoxViews
.
prototype
.
trimChat
=
function
()
{};
_converse
.
api
.
vcard
.
get
=
function
(
model
,
force
)
{
_converse
.
api
.
vcard
.
get
=
function
(
model
,
force
)
{
return
new
Promise
(
(
resolve
,
reject
)
=>
{
return
new
Promise
(
resolve
=>
{
let
jid
;
let
jid
;
if
(
_
.
isString
(
model
))
{
if
(
_
.
isString
(
model
))
{
jid
=
model
;
jid
=
model
;
...
@@ -263,9 +254,13 @@
...
@@ -263,9 +254,13 @@
return
async
done
=>
{
return
async
done
=>
{
const
_converse
=
await
initConverse
(
settings
,
spies
);
const
_converse
=
await
initConverse
(
settings
,
spies
);
async
function
_done
()
{
async
function
_done
()
{
await
_converse
.
api
.
user
.
logout
();
if
(
_converse
.
api
.
connection
.
connected
())
{
await
_converse
.
api
.
user
.
logout
();
}
const
el
=
document
.
querySelector
(
'
#conversejs
'
);
const
el
=
document
.
querySelector
(
'
#conversejs
'
);
el
.
parentElement
.
removeChild
(
el
);
if
(
el
)
{
el
.
parentElement
.
removeChild
(
el
);
}
done
();
done
();
}
}
await
Promise
.
all
((
promise_names
||
[]).
map
(
_converse
.
api
.
waitUntil
));
await
Promise
.
all
((
promise_names
||
[]).
map
(
_converse
.
api
.
waitUntil
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment