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
bcd68457
Commit
bcd68457
authored
Jul 22, 2018
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Show fingerprints in the user details modal
updates #497
parent
ce447e40
Changes
12
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
698 additions
and
383 deletions
+698
-383
css/converse.css
css/converse.css
+45
-38
dist/converse.js
dist/converse.js
+390
-291
locale/af/LC_MESSAGES/converse.po
locale/af/LC_MESSAGES/converse.po
+1
-1
sass/_forms.scss
sass/_forms.scss
+5
-0
sass/_profile.scss
sass/_profile.scss
+5
-0
sass/_variables.scss
sass/_variables.scss
+2
-0
spec/omemo.js
spec/omemo.js
+123
-6
spec/roster.js
spec/roster.js
+0
-11
src/converse-chatview.js
src/converse-chatview.js
+9
-12
src/converse-omemo.js
src/converse-omemo.js
+58
-11
src/templates/user_details_modal.html
src/templates/user_details_modal.html
+44
-13
src/utils/core.js
src/utils/core.js
+16
-0
No files found.
css/converse.css
View file @
bcd68457
...
@@ -2346,7 +2346,7 @@
...
@@ -2346,7 +2346,7 @@
--primary
:
#387592
;
--primary
:
#387592
;
--secondary
:
#6c757d
;
--secondary
:
#6c757d
;
--success
:
#3AA569
;
--success
:
#3AA569
;
--info
:
#
17a2b8
;
--info
:
#
3AA569
;
--warning
:
#ffc107
;
--warning
:
#ffc107
;
--danger
:
#E77051
;
--danger
:
#E77051
;
--light
:
#f8f9fa
;
--light
:
#f8f9fa
;
...
@@ -3594,24 +3594,24 @@
...
@@ -3594,24 +3594,24 @@
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
#conversejs
.btn-info
{
#conversejs
.btn-info
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
17a2b8
;
background-color
:
#
3AA569
;
border-color
:
#
17a2b8
;
}
border-color
:
#
3AA569
;
}
#conversejs
.btn-info
:hover
{
#conversejs
.btn-info
:hover
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
138496
;
background-color
:
#
308957
;
border-color
:
#
117a8b
;
}
border-color
:
#
2d7f51
;
}
#conversejs
.btn-info
:focus
,
#conversejs
.btn-info.focus
{
#conversejs
.btn-info
:focus
,
#conversejs
.btn-info.focus
{
box-shadow
:
0
0
0
0.2rem
rgba
(
23
,
162
,
184
,
0.5
);
}
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
#conversejs
.btn-info.disabled
,
#conversejs
.btn-info
:disabled
{
#conversejs
.btn-info.disabled
,
#conversejs
.btn-info
:disabled
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
17a2b8
;
background-color
:
#
3AA569
;
border-color
:
#
17a2b8
;
}
border-color
:
#
3AA569
;
}
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
:active
,
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
,
.show
>
#conversejs
.btn-info.dropdown-toggle
{
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
:active
,
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
,
.show
>
#conversejs
.btn-info.dropdown-toggle
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
117a8b
;
background-color
:
#
2d7f51
;
border-color
:
#
10707f
;
}
border-color
:
#
29764b
;
}
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
:active:focus
,
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
:focus
,
.show
>
#conversejs
.btn-info.dropdown-toggle
:focus
{
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
:active:focus
,
#conversejs
.btn-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
:focus
,
.show
>
#conversejs
.btn-info.dropdown-toggle
:focus
{
box-shadow
:
0
0
0
0.2rem
rgba
(
23
,
162
,
184
,
0.5
);
}
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
#conversejs
.btn-warning
{
#conversejs
.btn-warning
{
color
:
#212529
;
color
:
#212529
;
background-color
:
#ffc107
;
background-color
:
#ffc107
;
...
@@ -3753,25 +3753,25 @@
...
@@ -3753,25 +3753,25 @@
#conversejs
.btn-outline-success
:not
(
:disabled
)
:not
(
.disabled
)
:active:focus
,
#conversejs
.btn-outline-success
:not
(
:disabled
)
:not
(
.disabled
)
.active
:focus
,
.show
>
#conversejs
.btn-outline-success.dropdown-toggle
:focus
{
#conversejs
.btn-outline-success
:not
(
:disabled
)
:not
(
.disabled
)
:active:focus
,
#conversejs
.btn-outline-success
:not
(
:disabled
)
:not
(
.disabled
)
.active
:focus
,
.show
>
#conversejs
.btn-outline-success.dropdown-toggle
:focus
{
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
#conversejs
.btn-outline-info
{
#conversejs
.btn-outline-info
{
color
:
#
17a2b8
;
color
:
#
3AA569
;
background-color
:
transparent
;
background-color
:
transparent
;
background-image
:
none
;
background-image
:
none
;
border-color
:
#
17a2b8
;
}
border-color
:
#
3AA569
;
}
#conversejs
.btn-outline-info
:hover
{
#conversejs
.btn-outline-info
:hover
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
17a2b8
;
background-color
:
#
3AA569
;
border-color
:
#
17a2b8
;
}
border-color
:
#
3AA569
;
}
#conversejs
.btn-outline-info
:focus
,
#conversejs
.btn-outline-info.focus
{
#conversejs
.btn-outline-info
:focus
,
#conversejs
.btn-outline-info.focus
{
box-shadow
:
0
0
0
0.2rem
rgba
(
23
,
162
,
184
,
0.5
);
}
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
#conversejs
.btn-outline-info.disabled
,
#conversejs
.btn-outline-info
:disabled
{
#conversejs
.btn-outline-info.disabled
,
#conversejs
.btn-outline-info
:disabled
{
color
:
#
17a2b8
;
color
:
#
3AA569
;
background-color
:
transparent
;
}
background-color
:
transparent
;
}
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
:active
,
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
,
.show
>
#conversejs
.btn-outline-info.dropdown-toggle
{
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
:active
,
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
,
.show
>
#conversejs
.btn-outline-info.dropdown-toggle
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
17a2b8
;
background-color
:
#
3AA569
;
border-color
:
#
17a2b8
;
}
border-color
:
#
3AA569
;
}
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
:active:focus
,
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
:focus
,
.show
>
#conversejs
.btn-outline-info.dropdown-toggle
:focus
{
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
:active:focus
,
#conversejs
.btn-outline-info
:not
(
:disabled
)
:not
(
.disabled
)
.active
:focus
,
.show
>
#conversejs
.btn-outline-info.dropdown-toggle
:focus
{
box-shadow
:
0
0
0
0.2rem
rgba
(
23
,
162
,
184
,
0.5
);
}
box-shadow
:
0
0
0
0.2rem
rgba
(
58
,
165
,
105
,
0.5
);
}
#conversejs
.btn-outline-warning
{
#conversejs
.btn-outline-warning
{
color
:
#ffc107
;
color
:
#ffc107
;
background-color
:
transparent
;
background-color
:
transparent
;
...
@@ -4582,11 +4582,11 @@
...
@@ -4582,11 +4582,11 @@
background-color
:
#2d7f51
;
}
background-color
:
#2d7f51
;
}
#conversejs
.badge-info
{
#conversejs
.badge-info
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
17a2b8
;
}
background-color
:
#
3AA569
;
}
#conversejs
.badge-info
[
href
]
:hover
,
#conversejs
.badge-info
[
href
]
:focus
{
#conversejs
.badge-info
[
href
]
:hover
,
#conversejs
.badge-info
[
href
]
:focus
{
color
:
#fff
;
color
:
#fff
;
text-decoration
:
none
;
text-decoration
:
none
;
background-color
:
#
117a8b
;
}
background-color
:
#
2d7f51
;
}
#conversejs
.badge-warning
{
#conversejs
.badge-warning
{
color
:
#212529
;
color
:
#212529
;
background-color
:
#ffc107
;
}
background-color
:
#ffc107
;
}
...
@@ -4658,13 +4658,13 @@
...
@@ -4658,13 +4658,13 @@
#conversejs
.alert-success
.alert-link
{
#conversejs
.alert-success
.alert-link
{
color
:
#11301f
;
}
color
:
#11301f
;
}
#conversejs
.alert-info
{
#conversejs
.alert-info
{
color
:
#
0c5460
;
color
:
#
1e5637
;
background-color
:
#d
1ecf
1
;
background-color
:
#d
8ede
1
;
border-color
:
#
bee5eb
;
}
border-color
:
#
c8e6d5
;
}
#conversejs
.alert-info
hr
{
#conversejs
.alert-info
hr
{
border-top-color
:
#
abdde5
;
}
border-top-color
:
#
b6dec8
;
}
#conversejs
.alert-info
.alert-link
{
#conversejs
.alert-info
.alert-link
{
color
:
#
062c33
;
}
color
:
#
11301f
;
}
#conversejs
.alert-warning
{
#conversejs
.alert-warning
{
color
:
#856404
;
color
:
#856404
;
background-color
:
#fff3cd
;
background-color
:
#fff3cd
;
...
@@ -4782,15 +4782,15 @@
...
@@ -4782,15 +4782,15 @@
background-color
:
#1e5637
;
background-color
:
#1e5637
;
border-color
:
#1e5637
;
}
border-color
:
#1e5637
;
}
#conversejs
.list-group-item-info
{
#conversejs
.list-group-item-info
{
color
:
#
0c5460
;
color
:
#
1e5637
;
background-color
:
#
bee5eb
;
}
background-color
:
#
c8e6d5
;
}
#conversejs
.list-group-item-info.list-group-item-action
:hover
,
#conversejs
.list-group-item-info.list-group-item-action
:focus
{
#conversejs
.list-group-item-info.list-group-item-action
:hover
,
#conversejs
.list-group-item-info.list-group-item-action
:focus
{
color
:
#
0c5460
;
color
:
#
1e5637
;
background-color
:
#
abdde5
;
}
background-color
:
#
b6dec8
;
}
#conversejs
.list-group-item-info.list-group-item-action.active
{
#conversejs
.list-group-item-info.list-group-item-action.active
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#
0c5460
;
background-color
:
#
1e5637
;
border-color
:
#
0c5460
;
}
border-color
:
#
1e5637
;
}
#conversejs
.list-group-item-warning
{
#conversejs
.list-group-item-warning
{
color
:
#856404
;
color
:
#856404
;
background-color
:
#ffeeba
;
}
background-color
:
#ffeeba
;
}
...
@@ -5179,11 +5179,11 @@
...
@@ -5179,11 +5179,11 @@
#conversejs
button
.bg-success
:focus
{
#conversejs
button
.bg-success
:focus
{
background-color
:
#2d7f51
!important
;
}
background-color
:
#2d7f51
!important
;
}
#conversejs
.bg-info
{
#conversejs
.bg-info
{
background-color
:
#
17a2b8
!important
;
}
background-color
:
#
3AA569
!important
;
}
#conversejs
a
.bg-info
:hover
,
#conversejs
a
.bg-info
:focus
,
#conversejs
a
.bg-info
:hover
,
#conversejs
a
.bg-info
:focus
,
#conversejs
button
.bg-info
:hover
,
#conversejs
button
.bg-info
:hover
,
#conversejs
button
.bg-info
:focus
{
#conversejs
button
.bg-info
:focus
{
background-color
:
#
117a8b
!important
;
}
background-color
:
#
2d7f51
!important
;
}
#conversejs
.bg-warning
{
#conversejs
.bg-warning
{
background-color
:
#ffc107
!important
;
}
background-color
:
#ffc107
!important
;
}
#conversejs
a
.bg-warning
:hover
,
#conversejs
a
.bg-warning
:focus
,
#conversejs
a
.bg-warning
:hover
,
#conversejs
a
.bg-warning
:focus
,
...
@@ -5239,7 +5239,7 @@
...
@@ -5239,7 +5239,7 @@
#conversejs
.border-success
{
#conversejs
.border-success
{
border-color
:
#3AA569
!important
;
}
border-color
:
#3AA569
!important
;
}
#conversejs
.border-info
{
#conversejs
.border-info
{
border-color
:
#
17a2b8
!important
;
}
border-color
:
#
3AA569
!important
;
}
#conversejs
.border-warning
{
#conversejs
.border-warning
{
border-color
:
#ffc107
!important
;
}
border-color
:
#ffc107
!important
;
}
#conversejs
.border-danger
{
#conversejs
.border-danger
{
...
@@ -6792,9 +6792,9 @@
...
@@ -6792,9 +6792,9 @@
#conversejs
a
.text-success
:hover
,
#conversejs
a
.text-success
:focus
{
#conversejs
a
.text-success
:hover
,
#conversejs
a
.text-success
:focus
{
color
:
#2d7f51
!important
;
}
color
:
#2d7f51
!important
;
}
#conversejs
.text-info
{
#conversejs
.text-info
{
color
:
#
17a2b8
!important
;
}
color
:
#
3AA569
!important
;
}
#conversejs
a
.text-info
:hover
,
#conversejs
a
.text-info
:focus
{
#conversejs
a
.text-info
:hover
,
#conversejs
a
.text-info
:focus
{
color
:
#
117a8b
!important
;
}
color
:
#
2d7f51
!important
;
}
#conversejs
.text-warning
{
#conversejs
.text-warning
{
color
:
#ffc107
!important
;
}
color
:
#ffc107
!important
;
}
#conversejs
a
.text-warning
:hover
,
#conversejs
a
.text-warning
:focus
{
#conversejs
a
.text-warning
:hover
,
#conversejs
a
.text-warning
:focus
{
...
@@ -7213,6 +7213,9 @@ body.reset {
...
@@ -7213,6 +7213,9 @@ body.reset {
@media
screen
and
(
max-height
:
450px
)
{
@media
screen
and
(
max-height
:
450px
)
{
#conversejs
{
#conversejs
{
left
:
0
;
}
}
left
:
0
;
}
}
#conversejs
.btn--small
{
font-size
:
80%
;
font-weight
:
normal
;
}
#conversejs
form
.form-group
{
#conversejs
form
.form-group
{
margin-bottom
:
2em
;
}
margin-bottom
:
2em
;
}
#conversejs
form
.form-check-label
{
#conversejs
form
.form-check-label
{
...
@@ -7291,6 +7294,10 @@ body.reset {
...
@@ -7291,6 +7294,10 @@ body.reset {
#conversejs
#user-profile-modal
label
{
#conversejs
#user-profile-modal
label
{
font-weight
:
bold
;
}
font-weight
:
bold
;
}
#conversejs
.fingerprint-trust
{
display
:
flex
;
justify-content
:
space-between
;
font-size
:
95%
;
}
#conversejs
.chatbox-navback
{
#conversejs
.chatbox-navback
{
display
:
none
;
}
display
:
none
;
}
...
...
dist/converse.js
View file @
bcd68457
This diff is collapsed.
Click to expand it.
locale/af/LC_MESSAGES/converse.po
View file @
bcd68457
...
@@ -8,7 +8,7 @@ msgstr ""
...
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Converse.js 0.4\n"
"Project-Id-Version: Converse.js 0.4\n"
"Report-Msgid-Bugs-To: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-07-22 11:17+0200\n"
"POT-Creation-Date: 2018-07-22 11:17+0200\n"
"PO-Revision-Date: 2018-07-22 1
2:12
+0200\n"
"PO-Revision-Date: 2018-07-22 1
5:37
+0200\n"
"Last-Translator: JC Brand <jc@opkode.com>\n"
"Last-Translator: JC Brand <jc@opkode.com>\n"
"Language-Team: Afrikaans <https://hosted.weblate.org/projects/conversejs/"
"Language-Team: Afrikaans <https://hosted.weblate.org/projects/conversejs/"
"translations/af/>\n"
"translations/af/>\n"
...
...
sass/_forms.scss
View file @
bcd68457
#conversejs
{
#conversejs
{
.btn--small
{
font-size
:
80%
;
font-weight
:
normal
;
}
form
{
form
{
.form-group
{
.form-group
{
margin-bottom
:
2em
;
margin-bottom
:
2em
;
...
...
sass/_profile.scss
View file @
bcd68457
...
@@ -4,4 +4,9 @@
...
@@ -4,4 +4,9 @@
font-weight
:
bold
;
font-weight
:
bold
;
}
}
}
}
.fingerprint-trust
{
display
:
flex
;
justify-content
:
space-between
;
font-size
:
95%
;
}
}
}
sass/_variables.scss
View file @
bcd68457
...
@@ -34,6 +34,8 @@ $green: #3AA569;
...
@@ -34,6 +34,8 @@ $green: #3AA569;
$dark-green
:
#1E9652
;
$dark-green
:
#1E9652
;
$darkest-green
:
#0E763B
;
$darkest-green
:
#0E763B
;
$info
:
$green
!
default
;
$lightest-green
:
#E7FBF0
;
$lightest-green
:
#E7FBF0
;
$light-green
:
#5CBC86
;
$light-green
:
#5CBC86
;
$green
:
#3AA569
;
$green
:
#3AA569
;
...
...
spec/omemo.js
View file @
bcd68457
...
@@ -245,7 +245,7 @@
...
@@ -245,7 +245,7 @@
devicelist
=
_converse
.
devicelists
.
get
(
contact_jid
);
devicelist
=
_converse
.
devicelists
.
get
(
contact_jid
);
expect
(
devicelist
.
devices
.
length
).
toBe
(
1
);
expect
(
devicelist
.
devices
.
length
).
toBe
(
1
);
let
device
=
devicelist
.
devices
.
at
(
0
);
let
device
=
devicelist
.
devices
.
at
(
0
);
expect
(
device
.
get
(
'
bundle
'
).
identity_key
).
toBe
(
3333
);
expect
(
device
.
get
(
'
bundle
'
).
identity_key
).
toBe
(
'
3333
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
public_key
).
toBe
(
'
1111
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
public_key
).
toBe
(
'
1111
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
id
).
toBe
(
4223
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
id
).
toBe
(
4223
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
signature
).
toBe
(
'
2222
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
signature
).
toBe
(
'
2222
'
);
...
@@ -276,7 +276,7 @@
...
@@ -276,7 +276,7 @@
devicelist
=
_converse
.
devicelists
.
get
(
contact_jid
);
devicelist
=
_converse
.
devicelists
.
get
(
contact_jid
);
expect
(
devicelist
.
devices
.
length
).
toBe
(
1
);
expect
(
devicelist
.
devices
.
length
).
toBe
(
1
);
device
=
devicelist
.
devices
.
at
(
0
);
device
=
devicelist
.
devices
.
at
(
0
);
expect
(
device
.
get
(
'
bundle
'
).
identity_key
).
toBe
(
7777
);
expect
(
device
.
get
(
'
bundle
'
).
identity_key
).
toBe
(
'
7777
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
public_key
).
toBe
(
'
5555
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
public_key
).
toBe
(
'
5555
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
id
).
toBe
(
4223
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
id
).
toBe
(
4223
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
signature
).
toBe
(
'
6666
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
signature
).
toBe
(
'
6666
'
);
...
@@ -309,7 +309,7 @@
...
@@ -309,7 +309,7 @@
expect
(
devicelist
.
devices
.
at
(
0
).
get
(
'
id
'
)).
toBe
(
'
555
'
);
expect
(
devicelist
.
devices
.
at
(
0
).
get
(
'
id
'
)).
toBe
(
'
555
'
);
expect
(
devicelist
.
devices
.
at
(
1
).
get
(
'
id
'
)).
toBe
(
'
123456789
'
);
expect
(
devicelist
.
devices
.
at
(
1
).
get
(
'
id
'
)).
toBe
(
'
123456789
'
);
device
=
devicelist
.
devices
.
at
(
1
);
device
=
devicelist
.
devices
.
at
(
1
);
expect
(
device
.
get
(
'
bundle
'
).
identity_key
).
toBe
(
1111
);
expect
(
device
.
get
(
'
bundle
'
).
identity_key
).
toBe
(
'
1111
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
public_key
).
toBe
(
'
8888
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
public_key
).
toBe
(
'
8888
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
id
).
toBe
(
9999
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
id
).
toBe
(
9999
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
signature
).
toBe
(
'
3333
'
);
expect
(
device
.
get
(
'
bundle
'
).
signed_prekey
.
signature
).
toBe
(
'
3333
'
);
...
@@ -396,8 +396,15 @@
...
@@ -396,8 +396,15 @@
`</publish>`
+
`</publish>`
+
`</pubsub>`
+
`</pubsub>`
+
`</iq>`
)
`</iq>`
)
done
();
});
const
stanza
=
$iq
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
iq_stanza
.
getAttribute
(
'
id
'
),
'
to
'
:
_converse
.
bare_jid
,
'
type
'
:
'
result
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
return
_converse
.
api
.
waitUntil
(
'
OMEMOInitialized
'
);
}).
then
(
done
).
catch
(
_
.
partial
(
console
.
error
,
_
));
}));
}));
it
(
"
adds a toolbar button for starting an encrypted chat session
"
,
it
(
"
adds a toolbar button for starting an encrypted chat session
"
,
...
@@ -494,7 +501,6 @@
...
@@ -494,7 +501,6 @@
'
type
'
:
'
result
'
});
'
type
'
:
'
result
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
return
test_utils
.
waitUntil
(()
=>
{
return
test_utils
.
waitUntil
(()
=>
{
return
_
.
filter
(
return
_
.
filter
(
_converse
.
connection
.
IQ_stanzas
,
_converse
.
connection
.
IQ_stanzas
,
...
@@ -565,6 +571,117 @@
...
@@ -565,6 +571,117 @@
done
();
done
();
}).
catch
(
_
.
partial
(
console
.
error
,
_
));
}).
catch
(
_
.
partial
(
console
.
error
,
_
));
}));
}));
it
(
"
shows OMEMO device fingerprints in the user details modal
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
let
iq_stanza
;
test_utils
.
createContacts
(
_converse
,
'
current
'
,
1
);
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
// We simply emit, to avoid doing all the setup work
_converse
.
emit
(
'
OMEMOInitialized
'
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
show_modal_button
=
view
.
el
.
querySelector
(
'
.show-user-details-modal
'
);
show_modal_button
.
click
();
const
modal
=
view
.
user_details_modal
;
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
).
then
(()
=>
{
return
test_utils
.
waitUntil
(()
=>
{
return
_
.
filter
(
_converse
.
connection
.
IQ_stanzas
,
(
iq
)
=>
{
const
node
=
iq
.
nodeTree
.
querySelector
(
'
iq[to="
'
+
contact_jid
+
'
"] query[node="eu.siacs.conversations.axolotl.devicelist"]
'
);
if
(
node
)
{
iq_stanza
=
iq
.
nodeTree
;
}
return
node
;
}).
length
;});
}).
then
(()
=>
{
iq_stanza
;
expect
(
iq_stanza
.
outerHTML
).
toBe
(
`<iq type="get" from="dummy@localhost" to="max.frankfurter@localhost" xmlns="jabber:client" id="
${
iq_stanza
.
getAttribute
(
'
id
'
)}
">`
+
`<query xmlns="http://jabber.org/protocol/disco#items" node="eu.siacs.conversations.axolotl.devicelist"/>`
+
`</iq>`
);
const
stanza
=
$iq
({
'
from
'
:
contact_jid
,
'
id
'
:
iq_stanza
.
getAttribute
(
'
id
'
),
'
to
'
:
_converse
.
bare_jid
,
'
type
'
:
'
result
'
,
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#items
'
,
'
node
'
:
'
eu.siacs.conversations.axolotl.devicelist
'
}).
c
(
'
device
'
,
{
'
id
'
:
'
555
'
}).
up
()
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
).
then
(
function
()
{
return
test_utils
.
waitUntil
(()
=>
{
return
_
.
filter
(
_converse
.
connection
.
IQ_stanzas
,
(
iq
)
=>
{
const
node
=
iq
.
nodeTree
.
querySelector
(
'
iq[to="
'
+
contact_jid
+
'
"] items[node="eu.siacs.conversations.axolotl.bundles:555"]
'
);
if
(
node
)
{
iq_stanza
=
iq
.
nodeTree
;
}
return
node
;
}).
length
;});
});
}).
then
(()
=>
{
expect
(
iq_stanza
.
outerHTML
).
toBe
(
`<iq type="get" from="dummy@localhost" to="max.frankfurter@localhost" xmlns="jabber:client" id="
${
iq_stanza
.
getAttribute
(
'
id
'
)}
">`
+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`
+
`<items node="eu.siacs.conversations.axolotl.bundles:555"/>`
+
`</pubsub>`
+
`</iq>`
);
const
stanza
=
$iq
({
'
from
'
:
contact_jid
,
'
id
'
:
iq_stanza
.
getAttribute
(
'
id
'
),
'
to
'
:
_converse
.
bare_jid
,
'
type
'
:
'
result
'
,
}).
c
(
'
pubsub
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/pubsub
'
}).
c
(
'
items
'
,
{
'
node
'
:
"
eu.siacs.conversations.axolotl.bundles:555
"
})
.
c
(
'
item
'
)
.
c
(
'
bundle
'
,
{
'
xmlns
'
:
'
eu.siacs.conversations.axolotl
'
})
.
c
(
'
signedPreKeyPublic
'
,
{
'
signedPreKeyId
'
:
'
4223
'
}).
t
(
btoa
(
'
1111
'
)).
up
()
.
c
(
'
signedPreKeySignature
'
).
t
(
btoa
(
'
2222
'
)).
up
()
.
c
(
'
identityKey
'
).
t
(
btoa
(
'
3333
'
)).
up
()
.
c
(
'
prekeys
'
)
.
c
(
'
preKeyPublic
'
,
{
'
preKeyId
'
:
'
1
'
}).
t
(
btoa
(
'
1001
'
)).
up
()
.
c
(
'
preKeyPublic
'
,
{
'
preKeyId
'
:
'
2
'
}).
t
(
btoa
(
'
1002
'
)).
up
()
.
c
(
'
preKeyPublic
'
,
{
'
preKeyId
'
:
'
3
'
}).
t
(
btoa
(
'
1003
'
));
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
modal
=
view
.
user_details_modal
;
return
test_utils
.
waitUntil
(()
=>
modal
.
el
.
querySelectorAll
(
'
.fingerprints .fingerprint
'
).
length
);
}).
then
(()
=>
{
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
modal
=
view
.
user_details_modal
;
expect
(
modal
.
el
.
querySelectorAll
(
'
.fingerprints .fingerprint
'
).
length
).
toBe
(
1
);
const
el
=
modal
.
el
.
querySelector
(
'
.fingerprints .fingerprint
'
);
expect
(
el
.
textContent
).
toBe
(
'
f56d6351aa71cff0debea014d13525e42036187a
'
);
expect
(
modal
.
el
.
querySelectorAll
(
'
input[type="radio"]
'
).
length
).
toBe
(
2
);
let
trusted_radio
=
modal
.
el
.
querySelector
(
'
input[type="radio"][name="555"][value="1"]
'
);
expect
(
trusted_radio
.
checked
).
toBe
(
true
);
let
untrusted_radio
=
modal
.
el
.
querySelector
(
'
input[type="radio"][name="555"][value="-1"]
'
);
expect
(
untrusted_radio
.
checked
).
toBe
(
false
);
// Test that the device can be set to untrusted
untrusted_radio
.
click
();
trusted_radio
=
document
.
querySelector
(
'
input[type="radio"][name="555"][value="1"]
'
);
expect
(
trusted_radio
.
hasAttribute
(
'
checked
'
)).
toBe
(
false
);
untrusted_radio
=
document
.
querySelector
(
'
input[type="radio"][name="555"][value="-1"]
'
);
expect
(
untrusted_radio
.
hasAttribute
(
'
checked
'
)).
toBe
(
true
);
done
();
});
}));
});
});
describe
(
"
A chatbox with an active OMEMO session
"
,
function
()
{
describe
(
"
A chatbox with an active OMEMO session
"
,
function
()
{
...
...
spec/roster.js
View file @
bcd68457
...
@@ -389,7 +389,6 @@
...
@@ -389,7 +389,6 @@
function
(
done
,
_converse
)
{
function
(
done
,
_converse
)
{
_converse
.
roster_groups
=
true
;
_converse
.
roster_groups
=
true
;
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
_converse
.
rosterview
.
render
();
_converse
.
rosterview
.
render
();
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
...
@@ -430,7 +429,6 @@
...
@@ -430,7 +429,6 @@
function
(
done
,
_converse
)
{
function
(
done
,
_converse
)
{
_converse
.
roster_groups
=
true
;
_converse
.
roster_groups
=
true
;
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
_converse
.
rosterview
.
render
();
_converse
.
rosterview
.
render
();
...
@@ -477,7 +475,6 @@
...
@@ -477,7 +475,6 @@
_converse
.
roster_groups
=
true
;
_converse
.
roster_groups
=
true
;
var
groups
=
[
'
colleagues
'
,
'
friends
'
];
var
groups
=
[
'
colleagues
'
,
'
friends
'
];
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
_converse
.
rosterview
.
render
();
_converse
.
rosterview
.
render
();
...
@@ -576,7 +573,6 @@
...
@@ -576,7 +573,6 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
function
(
done
,
_converse
)
{
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
_converse
.
roster
.
create
({
_converse
.
roster
.
create
({
...
@@ -726,7 +722,6 @@
...
@@ -726,7 +722,6 @@
var
i
,
t
;
var
i
,
t
;
test_utils
.
openControlBox
();
test_utils
.
openControlBox
();
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
for
(
i
=
0
;
i
<
mock
.
pend_names
.
length
;
i
++
)
{
for
(
i
=
0
;
i
<
mock
.
pend_names
.
length
;
i
++
)
{
_converse
.
roster
.
create
({
_converse
.
roster
.
create
({
...
@@ -908,7 +903,6 @@
...
@@ -908,7 +903,6 @@
test_utils
.
waitUntil
(()
=>
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
,
700
)
test_utils
.
waitUntil
(()
=>
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
,
700
)
.
then
(
function
()
{
.
then
(
function
()
{
var
jid
,
t
;
var
jid
,
t
;
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
...
@@ -935,7 +929,6 @@
...
@@ -935,7 +929,6 @@
return
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
;
return
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
;
},
700
).
then
(
function
()
{
},
700
).
then
(
function
()
{
var
jid
,
t
;
var
jid
,
t
;
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
...
@@ -963,7 +956,6 @@
...
@@ -963,7 +956,6 @@
return
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
;
return
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
;
},
700
).
then
(
function
()
{
},
700
).
then
(
function
()
{
var
jid
,
t
;
var
jid
,
t
;
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
...
@@ -991,7 +983,6 @@
...
@@ -991,7 +983,6 @@
return
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
;
return
$
(
_converse
.
rosterview
.
el
).
find
(
'
.roster-group li
'
).
length
;
},
700
).
then
(
function
()
{
},
700
).
then
(
function
()
{
var
jid
,
t
;
var
jid
,
t
;
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
...
@@ -1020,7 +1011,6 @@
...
@@ -1020,7 +1011,6 @@
},
500
)
},
500
)
.
then
(
function
()
{
.
then
(
function
()
{
var
jid
,
t
;
var
jid
,
t
;
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
var
$roster
=
$
(
_converse
.
rosterview
.
el
);
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
mock
.
cur_names
.
length
;
i
++
)
{
...
@@ -1151,7 +1141,6 @@
...
@@ -1151,7 +1141,6 @@
names
.
push
(
$
(
item
).
text
().
replace
(
/^
\s
+|
\s
+$/g
,
''
));
names
.
push
(
$
(
item
).
text
().
replace
(
/^
\s
+|
\s
+$/g
,
''
));
}
}
};
};
spyOn
(
_converse
,
'
emit
'
);
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
rosterview
,
'
update
'
).
and
.
callThrough
();
spyOn
(
_converse
.
controlboxtoggle
,
'
showControlBox
'
).
and
.
callThrough
();
spyOn
(
_converse
.
controlboxtoggle
,
'
showControlBox
'
).
and
.
callThrough
();
for
(
i
=
0
;
i
<
mock
.
req_names
.
length
;
i
++
)
{
for
(
i
=
0
;
i
<
mock
.
req_names
.
length
;
i
++
)
{
...
...
src/converse-chatview.js
View file @
bcd68457
...
@@ -239,32 +239,29 @@
...
@@ -239,32 +239,29 @@
events
:
{
events
:
{
'
click button.remove-contact
'
:
'
removeContact
'
,
'
click button.remove-contact
'
:
'
removeContact
'
,
'
click button.refresh-contact
'
:
'
refreshContact
'
'
click button.refresh-contact
'
:
'
refreshContact
'
,
'
click .fingerprint-trust .btn input
'
:
'
toggleDeviceTrust
'
},
},
initialize
()
{
initialize
()
{
_converse
.
BootstrapModal
.
prototype
.
initialize
.
apply
(
this
,
arguments
);
_converse
.
BootstrapModal
.
prototype
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
contactAdded
'
,
this
.
registerContactEventHandlers
,
this
);
this
.
model
.
on
(
'
contactAdded
'
,
this
.
registerContactEventHandlers
,
this
);
this
.
model
.
on
(
'
change
'
,
this
.
render
,
this
);
this
.
registerContactEventHandlers
();
this
.
registerContactEventHandlers
();
_converse
.
emit
(
'
userDetailsModalInitialized
'
,
this
.
model
);
},
},
toHTML
()
{
toHTML
()
{
return
tpl_user_details_modal
(
_
.
extend
(
return
tpl_user_details_modal
(
_
.
extend
(
this
.
model
.
toJSON
(),
this
.
model
.
toJSON
(),
this
.
model
.
vcard
.
toJSON
(),
{
this
.
model
.
vcard
.
toJSON
(),
{
'
_
'
:
_
,
'
__
'
:
__
,
'
view
'
:
this
,
'
_converse
'
:
_converse
,
'
allow_contact_removal
'
:
_converse
.
allow_contact_removal
,
'
allow_contact_removal
'
:
_converse
.
allow_contact_removal
,
'
alt_profile_image
'
:
__
(
"
The User's Profile Image
"
),
'
display_name
'
:
this
.
model
.
getDisplayName
(),
'
display_name
'
:
this
.
model
.
getDisplayName
(),
'
is_roster_contact
'
:
!
_
.
isUndefined
(
this
.
model
.
contact
),
'
is_roster_contact
'
:
!
_
.
isUndefined
(
this
.
model
.
contact
)
'
label_close
'
:
__
(
'
Close
'
),
'
label_email
'
:
__
(
'
Email
'
),
'
label_fullname
'
:
__
(
'
Full Name
'
),
'
label_jid
'
:
__
(
'
Jabber ID
'
),
'
label_nickname
'
:
__
(
'
Nickname
'
),
'
label_remove
'
:
__
(
'
Remove as contact
'
),
'
label_refresh
'
:
__
(
'
Refresh
'
),
'
label_role
'
:
__
(
'
Role
'
),
'
label_url
'
:
__
(
'
URL
'
)
}));
}));
},
},
...
...
src/converse-omemo.js
View file @
bcd68457
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
}
}
});
});
return
{
return
{
'
identity_key
'
:
parseInt
(
bundle_el
.
querySelector
(
'
identityKey
'
).
textContent
,
10
)
,
'
identity_key
'
:
bundle_el
.
querySelector
(
'
identityKey
'
).
textContent
,
'
signed_prekey
'
:
{
'
signed_prekey
'
:
{
'
id
'
:
parseInt
(
signed_prekey_public_el
.
getAttribute
(
'
signedPreKeyId
'
),
10
),
'
id
'
:
parseInt
(
signed_prekey_public_el
.
getAttribute
(
'
signedPreKeyId
'
),
10
),
'
public_key
'
:
signed_prekey_public_el
.
textContent
,
'
public_key
'
:
signed_prekey_public_el
.
textContent
,
...
@@ -65,6 +65,27 @@
...
@@ -65,6 +65,27 @@
overrides
:
{
overrides
:
{
UserDetailsModal
:
{
events
:
{
'
click .fingerprint-trust .btn input
'
:
'
toggleDeviceTrust
'
},
initialize
()
{
const
{
_converse
}
=
this
.
__super__
;
const
jid
=
this
.
model
.
get
(
'
jid
'
);
this
.
devicelist
=
_converse
.
devicelists
.
get
(
jid
)
||
_converse
.
devicelists
.
create
({
'
jid
'
:
jid
});
this
.
devicelist
.
devices
.
on
(
'
change:bundle
'
,
this
.
render
,
this
);
this
.
devicelist
.
devices
.
on
(
'
change:trusted
'
,
this
.
render
,
this
);
return
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
},
toggleDeviceTrust
(
ev
)
{
const
radio
=
ev
.
target
;
const
device
=
this
.
devicelist
.
devices
.
get
(
radio
.
getAttribute
(
'
name
'
));
device
.
save
(
'
trusted
'
,
parseInt
(
radio
.
value
,
10
));
}
},
ChatBox
:
{
ChatBox
:
{
getBundlesAndBuildSessions
()
{
getBundlesAndBuildSessions
()
{
...
@@ -77,7 +98,6 @@
...
@@ -77,7 +98,6 @@
this
.
buildSessions
(
devices
)
this
.
buildSessions
(
devices
)
.
then
(()
=>
resolve
(
devices
))
.
then
(()
=>
resolve
(
devices
))
.
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
.
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
...
@@ -194,6 +214,27 @@
...
@@ -194,6 +214,27 @@
_converse
.
NUM_PREKEYS
=
100
;
// Set here so that tests can override
_converse
.
NUM_PREKEYS
=
100
;
// Set here so that tests can override
function
generateFingerprint
(
device
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
device
.
getBundle
().
then
((
bundle
)
=>
{
// TODO: only generate fingerprints when necessary
crypto
.
subtle
.
digest
(
'
SHA-1
'
,
u
.
base64ToArrayBuffer
(
bundle
[
'
identity_key
'
]))
.
then
((
fp
)
=>
{
bundle
[
'
fingerprint
'
]
=
u
.
arrayBufferToHex
(
fp
);
device
.
save
(
'
bundle
'
,
bundle
);
device
.
trigger
(
'
change:bundle
'
);
// Doesn't get triggered automatically due to pass-by-reference
resolve
();
}).
catch
(
reject
);
});
});
}
_converse
.
getFingerprintsForContact
=
function
(
jid
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
_converse
.
getDevicesForContact
(
jid
)
.
then
((
devices
)
=>
Promise
.
all
(
devices
.
map
(
d
=>
generateFingerprint
(
d
))).
then
(
resolve
).
catch
(
reject
));
});
}
_converse
.
getDevicesForContact
=
function
(
jid
)
{
_converse
.
getDevicesForContact
=
function
(
jid
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
...
@@ -405,14 +446,15 @@
...
@@ -405,14 +446,15 @@
'
from
'
:
_converse
.
bare_jid
,
'
from
'
:
_converse
.
bare_jid
,
'
to
'
:
this
.
get
(
'
jid
'
)
'
to
'
:
this
.
get
(
'
jid
'
)
}).
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
}).
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
xmlns
'
:
`
${
Strophe
.
NS
.
OMEMO_BUNDLES
}
:
${
this
.
get
(
'
id
'
)}
`
});
.
c
(
'
items
'
,
{
'
node
'
:
`
${
Strophe
.
NS
.
OMEMO_BUNDLES
}
:
${
this
.
get
(
'
id
'
)}
`
});
_converse
.
connection
.
sendIQ
(
_converse
.
connection
.
sendIQ
(
stanza
,
stanza
,
(
iq
)
=>
{
(
iq
)
=>
{
const
publish_el
=
sizzle
(
`items[node="
${
Strophe
.
NS
.
OMEMO_BUNDLES
}
:
${
this
.
get
(
'
id
'
)}
"]`
,
stanza
).
pop
();
const
publish_el
=
sizzle
(
`items[node="
${
Strophe
.
NS
.
OMEMO_BUNDLES
}
:
${
this
.
get
(
'
id
'
)}
"]`
,
iq
).
pop
(),
const
bundle_el
=
sizzle
(
`bundle[xmlns="
${
Strophe
.
NS
.
OMEMO
}
"]`
,
publish_el
).
pop
();
bundle_el
=
sizzle
(
`bundle[xmlns="
${
Strophe
.
NS
.
OMEMO
}
"]`
,
publish_el
).
pop
(),
this
.
save
(
parseBundle
(
bundle_el
));
bundle
=
parseBundle
(
bundle_el
);
resolve
();
this
.
save
(
'
bundle
'
,
bundle
);
resolve
(
bundle
);
},
},
reject
,
reject
,
_converse
.
IQ_TIMEOUT
_converse
.
IQ_TIMEOUT
...
@@ -479,7 +521,7 @@
...
@@ -479,7 +521,7 @@
(
iq
)
=>
{
(
iq
)
=>
{
_
.
forEach
(
_
.
forEach
(
iq
.
querySelectorAll
(
'
device
'
),
iq
.
querySelectorAll
(
'
device
'
),
(
dev
)
=>
this
.
devices
.
create
({
'
id
'
:
dev
.
getAttribute
(
'
id
'
)})
(
dev
)
=>
this
.
devices
.
create
({
'
id
'
:
dev
.
getAttribute
(
'
id
'
)
,
'
jid
'
:
this
.
get
(
'
jid
'
)
})
);
);
resolve
();
resolve
();
},
},
...
@@ -493,7 +535,7 @@
...
@@ -493,7 +535,7 @@
* server.
* server.
* https://xmpp.org/extensions/xep-0384.html#usecases-announcing
* https://xmpp.org/extensions/xep-0384.html#usecases-announcing
*/
*/
this
.
devices
.
create
({
'
id
'
:
device_id
});
this
.
devices
.
create
({
'
id
'
:
device_id
,
'
jid
'
:
this
.
get
(
'
jid
'
)
});
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
stanza
=
$iq
({
const
stanza
=
$iq
({
'
from
'
:
_converse
.
bare_jid
,
'
from
'
:
_converse
.
bare_jid
,
...
@@ -589,7 +631,7 @@
...
@@ -589,7 +631,7 @@
jid
=
stanza
.
getAttribute
(
'
from
'
),
jid
=
stanza
.
getAttribute
(
'
from
'
),
bundle_el
=
sizzle
(
`item > bundle`
,
items_el
).
pop
(),
bundle_el
=
sizzle
(
`item > bundle`
,
items_el
).
pop
(),
devicelist
=
_converse
.
devicelists
.
get
(
jid
)
||
_converse
.
devicelists
.
create
({
'
jid
'
:
jid
}),
devicelist
=
_converse
.
devicelists
.
get
(
jid
)
||
_converse
.
devicelists
.
create
({
'
jid
'
:
jid
}),
device
=
devicelist
.
devices
.
get
(
device_id
)
||
devicelist
.
devices
.
create
({
'
id
'
:
device_id
});
device
=
devicelist
.
devices
.
get
(
device_id
)
||
devicelist
.
devices
.
create
({
'
id
'
:
device_id
,
'
jid
'
:
jid
});
device
.
save
({
'
bundle
'
:
parseBundle
(
bundle_el
)});
device
.
save
({
'
bundle
'
:
parseBundle
(
bundle_el
)});
}
}
...
@@ -613,7 +655,7 @@
...
@@ -613,7 +655,7 @@
if
(
dev
)
{
if
(
dev
)
{
dev
.
save
({
'
active
'
:
true
});
dev
.
save
({
'
active
'
:
true
});
}
else
{
}
else
{
devices
.
create
({
'
id
'
:
device_id
})
devices
.
create
({
'
id
'
:
device_id
,
'
jid
'
:
jid
})
}
}
});
});
// Make sure our own device is on the list (i.e. if it was
// Make sure our own device is on the list (i.e. if it was
...
@@ -661,6 +703,11 @@
...
@@ -661,6 +703,11 @@
_converse
.
api
.
listen
.
on
(
'
statusInitialized
'
,
initOMEMO
);
_converse
.
api
.
listen
.
on
(
'
statusInitialized
'
,
initOMEMO
);
_converse
.
api
.
listen
.
on
(
'
addClientFeatures
'
,
_converse
.
api
.
listen
.
on
(
'
addClientFeatures
'
,
()
=>
_converse
.
api
.
disco
.
own
.
features
.
add
(
Strophe
.
NS
.
OMEMO_DEVICELIST
+
"
notify
"
));
()
=>
_converse
.
api
.
disco
.
own
.
features
.
add
(
Strophe
.
NS
.
OMEMO_DEVICELIST
+
"
notify
"
));
_converse
.
api
.
listen
.
on
(
'
userDetailsModalInitialized
'
,
(
contact
)
=>
{
const
jid
=
contact
.
get
(
'
jid
'
);
_converse
.
getFingerprintsForContact
(
jid
).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
ERROR
));
});
}
}
});
});
}));
}));
src/templates/user_details_modal.html
View file @
bcd68457
<div
class=
"modal fade"
id=
"user-
profile-modal"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"user-profile
-modal-label"
aria-hidden=
"true"
>
<div
class=
"modal fade"
id=
"user-
details-modal"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"user-details
-modal-label"
aria-hidden=
"true"
>
<div
class=
"modal-dialog"
role=
"document"
>
<div
class=
"modal-dialog"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
id=
"user-
profile
-modal-label"
>
{{{o.display_name}}}
</h5>
<h5
class=
"modal-title"
id=
"user-
details
-modal-label"
>
{{{o.display_name}}}
</h5>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"{{{o.
label_close
}}}"
><span
aria-hidden=
"true"
>
×
</span></button>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"{{{o.
__('Close')
}}}"
><span
aria-hidden=
"true"
>
×
</span></button>
</div>
</div>
<div
class=
"modal-body"
>
<div
class=
"modal-body"
>
{[ if (o.image) { ]}
{[ if (o.image) { ]}
<img
alt=
"{{{o.
alt_profile_image
}}}"
<img
alt=
"{{{o.
__('The User\'s Profile Image')
}}}"
class=
"img-thumbnail avatar align-self-center mb-3"
class=
"img-thumbnail avatar align-self-center mb-3"
height=
"100"
width=
"100"
src=
"data:{{{o.image_type}}};base64,{{{o.image}}}"
/>
height=
"100"
width=
"100"
src=
"data:{{{o.image_type}}};base64,{{{o.image}}}"
/>
{[ } ]}
{[ } ]}
{[ if (o.fullname) { ]}
{[ if (o.fullname) { ]}
<p><label>
{{{o.
label_fullname
}}}:
</label>
{{{o.fullname}}}
</p>
<p><label>
{{{o.
__('Full Name')
}}}:
</label>
{{{o.fullname}}}
</p>
{[ } ]}
{[ } ]}
<p><label>
{{{o.
label_jid
}}}:
</label>
{{{o.jid}}}
</p>
<p><label>
{{{o.
__('XMPP Address')
}}}:
</label>
{{{o.jid}}}
</p>
{[ if (o.nickname) { ]}
{[ if (o.nickname) { ]}
<p><label>
{{{o.
label_nickname
}}}:
</label>
{{{o.nickname}}}
</p>
<p><label>
{{{o.
__('Nickname')
}}}:
</label>
{{{o.nickname}}}
</p>
{[ } ]}
{[ } ]}
{[ if (o.url) { ]}
{[ if (o.url) { ]}
<p><label>
{{{o.
label_url
}}}:
</label>
<a
target=
"_blank"
rel=
"noopener"
href=
"{{{o.url}}}"
>
{{{o.url}}}
</a></p>
<p><label>
{{{o.
__('URL')
}}}:
</label>
<a
target=
"_blank"
rel=
"noopener"
href=
"{{{o.url}}}"
>
{{{o.url}}}
</a></p>
{[ } ]}
{[ } ]}
{[ if (o.email) { ]}
{[ if (o.email) { ]}
<p><label>
{{{o.
label_email
}}}:
</label>
<a
href=
"mailto:{{{o.email}}}"
>
{{{o.email}}}
</a></p>
<p><label>
{{{o.
__('Email')
}}}:
</label>
<a
href=
"mailto:{{{o.email}}}"
>
{{{o.email}}}
</a></p>
{[ } ]}
{[ } ]}
{[ if (o.role) { ]}
{[ if (o.role) { ]}
<p><label>
{{{o.label_role}}}:
</label>
{{{o.role}}}
</p>
<p><label>
{{{o.__('Role')}}}:
</label>
{{{o.role}}}
</p>
{[ } ]}
{[ if (o._converse.pluggable.plugins['converse-omemo'].enabled()) { ]}
<hr>
<ul
class=
"list-group fingerprints"
>
<li
class=
"list-group-item active"
>
{{{o.__('OMEMO Fingerprints')}}}
</li>
{[ if (!o.view.devicelist.devices) { ]}
<li
class=
"list-group-item"
><span
class=
"spinner fa fa-spinner centered"
/></li>
{[ } ]}
{[ if (o.view.devicelist.devices) { ]}
{[ o.view.devicelist.devices.each(function (device) { ]}
{[ if (device.get('bundle')
&&
device.get('bundle').fingerprint) { ]}
<li
class=
"list-group-item"
>
<form
class=
"fingerprint-trust"
>
<span
class=
"fingerprint"
>
{{{device.get('bundle').fingerprint}}}
</span>
<div
class=
"btn-group btn-group-toggle"
>
<label
class=
"btn btn--small {[ if (device.get('trusted') !== -1) { ]} btn-primary active {[ } else { ]} btn-secondary {[ } ]}"
>
<input
type=
"radio"
name=
"{{{device.get('id')}}}"
value=
"1"
{[
if
(
device
.
get
('
trusted
')
!==
-1
)
{
]}
checked=
"checked"
{[
}
]}
>
{{{o.__('Trusted')}}}
</label>
<label
class=
"btn btn--small {[ if (device.get('trusted') === -1) { ]} btn-primary active {[ } else { ]} btn-secondary {[ } ]}"
>
<input
type=
"radio"
name=
"{{{device.get('id')}}}"
value=
"-1"
{[
if
(
device
.
get
('
trusted
'
) =
==
-1
)
{
]}
checked=
"checked"
{[
}
]}
>
{{{o.__('Untrusted')}}}
</label>
</div>
</form>
</li>
{[ } ]}
{[ }); ]}
{[ } ]}
</ul>
{[ } ]}
{[ } ]}
</div>
</div>
<div
class=
"modal-footer"
>
<div
class=
"modal-footer"
>
{[ if (o.allow_contact_removal
&&
o.is_roster_contact) { ]}
{[ if (o.allow_contact_removal
&&
o.is_roster_contact) { ]}
<button
type=
"button"
class=
"btn btn-danger remove-contact"
><i
class=
"fa fa-trash"
>
</i>
{{{o.
label_remove
}}}
</button>
<button
type=
"button"
class=
"btn btn-danger remove-contact"
><i
class=
"fa fa-trash"
>
</i>
{{{o.
__('Remove as contact')
}}}
</button>
{[ } ]}
{[ } ]}
<button
type=
"button"
class=
"btn btn-info refresh-contact"
><i
class=
"fa fa-refresh"
>
</i>
{{{o.
label_refresh
}}}
</button>
<button
type=
"button"
class=
"btn btn-info refresh-contact"
><i
class=
"fa fa-refresh"
>
</i>
{{{o.
__('Refresh')
}}}
</button>
<button
type=
"button"
class=
"btn btn-secondary"
data-dismiss=
"modal"
>
{{{o.
label_close
}}}
</button>
<button
type=
"button"
class=
"btn btn-secondary"
data-dismiss=
"modal"
>
{{{o.
__('Close')
}}}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
src/utils/core.js
View file @
bcd68457
...
@@ -846,6 +846,22 @@
...
@@ -846,6 +846,22 @@
return
result
;
return
result
;
};
};
u
.
arrayBufferToHex
=
function
(
ab
)
{
const
hexCodes
=
[];
const
padding
=
'
00000000
'
;
const
view
=
new
window
.
DataView
(
ab
);
for
(
var
i
=
0
;
i
<
view
.
byteLength
;
i
+=
4
)
{
// Using getUint32 reduces the number of iterations needed (we process 4 bytes each time)
const
value
=
view
.
getUint32
(
i
)
// toString(16) will give the hex representation of the number without padding
const
stringValue
=
value
.
toString
(
16
)
// We use concatenation and slice for padding
const
paddedValue
=
(
padding
+
stringValue
).
slice
(
-
padding
.
length
)
hexCodes
.
push
(
paddedValue
);
}
return
hexCodes
.
join
(
""
);
};
u
.
arrayBufferToString
=
function
(
ab
)
{
u
.
arrayBufferToString
=
function
(
ab
)
{
var
enc
=
new
TextDecoder
(
"
utf-8
"
);
var
enc
=
new
TextDecoder
(
"
utf-8
"
);
return
enc
.
decode
(
new
Uint8Array
(
ab
));
return
enc
.
decode
(
new
Uint8Array
(
ab
));
...
...
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