quickblox 2.17.2-beta.2-logger → 2.17.3-logger

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/LICENSE +330 -201
  2. package/README.md +2 -2
  3. package/package.json +1 -2
  4. package/quickblox.js +19389 -21772
  5. package/quickblox.min.js +1 -1
  6. package/src/libs/strophe/strophe.common.js +6657 -0
  7. package/src/libs/strophe/strophe.esm.js +6649 -0
  8. package/src/libs/strophe/strophe.umd.js +6862 -0
  9. package/src/libs/strophe/strophe.umd.min.js +1 -0
  10. package/src/modules/chat/qbChat.js +131 -11
  11. package/src/modules/webrtc/qbWebRTCSignalingProcessor.js +2 -1
  12. package/src/modules/webrtc/qbWebRTCSignalingProvider.js +2 -1
  13. package/src/qbConfig.js +2 -2
  14. package/src/qbProxy.js +1 -1
  15. package/src/qbStrophe.js +2 -6
  16. package/strophejs-1.4.0/.eslintrc.json +264 -0
  17. package/strophejs-1.4.0/.gitattributes +1 -0
  18. package/strophejs-1.4.0/CHANGELOG.md +250 -0
  19. package/strophejs-1.4.0/LICENSE.txt +19 -0
  20. package/strophejs-1.4.0/Makefile +92 -0
  21. package/strophejs-1.4.0/README.md +45 -0
  22. package/strophejs-1.4.0/RELEASE_CHECKLIST.md +16 -0
  23. package/strophejs-1.4.0/contrib/discojs/README.txt +42 -0
  24. package/strophejs-1.4.0/contrib/discojs/css/disco.css +16 -0
  25. package/strophejs-1.4.0/contrib/discojs/index.html +47 -0
  26. package/strophejs-1.4.0/contrib/discojs/punjab.tac +18 -0
  27. package/strophejs-1.4.0/contrib/discojs/scripts/basic.js +102 -0
  28. package/strophejs-1.4.0/contrib/discojs/scripts/disco.js +60 -0
  29. package/strophejs-1.4.0/docs.css +797 -0
  30. package/strophejs-1.4.0/examples/amd.html +21 -0
  31. package/strophejs-1.4.0/examples/attach/README +37 -0
  32. package/strophejs-1.4.0/examples/attach/__init__.py +0 -0
  33. package/strophejs-1.4.0/examples/attach/attacher/__init__.py +0 -0
  34. package/strophejs-1.4.0/examples/attach/attacher/views.py +18 -0
  35. package/strophejs-1.4.0/examples/attach/boshclient.py +158 -0
  36. package/strophejs-1.4.0/examples/attach/manage.py +11 -0
  37. package/strophejs-1.4.0/examples/attach/settings.py +85 -0
  38. package/strophejs-1.4.0/examples/attach/templates/attacher/index.html +88 -0
  39. package/strophejs-1.4.0/examples/attach/urls.py +19 -0
  40. package/strophejs-1.4.0/examples/basic.html +23 -0
  41. package/strophejs-1.4.0/examples/basic.js +73 -0
  42. package/strophejs-1.4.0/examples/echobot.html +25 -0
  43. package/strophejs-1.4.0/examples/echobot.js +79 -0
  44. package/strophejs-1.4.0/examples/main.js +59 -0
  45. package/strophejs-1.4.0/examples/prebind.html +39 -0
  46. package/strophejs-1.4.0/examples/prebind.js +103 -0
  47. package/strophejs-1.4.0/examples/restore.html +24 -0
  48. package/strophejs-1.4.0/examples/restore.js +71 -0
  49. package/strophejs-1.4.0/package-lock.json +8631 -0
  50. package/strophejs-1.4.0/package.json +84 -0
  51. package/strophejs-1.4.0/rollup.config.js +76 -0
  52. package/strophejs-1.4.0/src/bosh.js +916 -0
  53. package/strophejs-1.4.0/src/core.js +3530 -0
  54. package/strophejs-1.4.0/src/md5.js +204 -0
  55. package/strophejs-1.4.0/src/sha1.js +172 -0
  56. package/strophejs-1.4.0/src/shared-connection-worker.js +114 -0
  57. package/strophejs-1.4.0/src/shims.js +123 -0
  58. package/strophejs-1.4.0/src/strophe.js +14 -0
  59. package/strophejs-1.4.0/src/utils.js +63 -0
  60. package/strophejs-1.4.0/src/websocket.js +557 -0
  61. package/strophejs-1.4.0/src/worker-websocket.js +150 -0
  62. package/strophejs-1.4.0/tests/index.html +21 -0
  63. package/strophejs-1.4.0/tests/main.js +49 -0
  64. package/strophejs-1.4.0/tests/tests.js +929 -0
  65. package/strophejs-1.6.1/.eslintrc.json +264 -0
  66. package/strophejs-1.6.1/.gitattributes +1 -0
  67. package/strophejs-1.6.1/.nvmrc +1 -0
  68. package/strophejs-1.6.1/CHANGELOG.md +288 -0
  69. package/strophejs-1.6.1/LICENSE.txt +19 -0
  70. package/strophejs-1.6.1/Makefile +92 -0
  71. package/strophejs-1.6.1/README.md +46 -0
  72. package/strophejs-1.6.1/RELEASE_CHECKLIST.md +18 -0
  73. package/strophejs-1.6.1/babel.config.json +10 -0
  74. package/strophejs-1.6.1/contrib/discojs/README.txt +42 -0
  75. package/strophejs-1.6.1/contrib/discojs/css/disco.css +16 -0
  76. package/strophejs-1.6.1/contrib/discojs/index.html +47 -0
  77. package/strophejs-1.6.1/contrib/discojs/punjab.tac +18 -0
  78. package/strophejs-1.6.1/contrib/discojs/scripts/basic.js +102 -0
  79. package/strophejs-1.6.1/contrib/discojs/scripts/disco.js +60 -0
  80. package/strophejs-1.6.1/docs.css +797 -0
  81. package/strophejs-1.6.1/examples/amd.html +21 -0
  82. package/strophejs-1.6.1/examples/attach/README +37 -0
  83. package/strophejs-1.6.1/examples/attach/__init__.py +0 -0
  84. package/strophejs-1.6.1/examples/attach/attacher/__init__.py +0 -0
  85. package/strophejs-1.6.1/examples/attach/attacher/views.py +18 -0
  86. package/strophejs-1.6.1/examples/attach/boshclient.py +158 -0
  87. package/strophejs-1.6.1/examples/attach/manage.py +11 -0
  88. package/strophejs-1.6.1/examples/attach/settings.py +85 -0
  89. package/strophejs-1.6.1/examples/attach/templates/attacher/index.html +88 -0
  90. package/strophejs-1.6.1/examples/attach/urls.py +19 -0
  91. package/strophejs-1.6.1/examples/basic.html +23 -0
  92. package/strophejs-1.6.1/examples/basic.js +73 -0
  93. package/strophejs-1.6.1/examples/echobot.html +25 -0
  94. package/strophejs-1.6.1/examples/echobot.js +79 -0
  95. package/strophejs-1.6.1/examples/main.js +59 -0
  96. package/strophejs-1.6.1/examples/prebind.html +39 -0
  97. package/strophejs-1.6.1/examples/prebind.js +103 -0
  98. package/strophejs-1.6.1/examples/restore.html +24 -0
  99. package/strophejs-1.6.1/examples/restore.js +71 -0
  100. package/strophejs-1.6.1/package-lock.json +18461 -0
  101. package/strophejs-1.6.1/package.json +87 -0
  102. package/strophejs-1.6.1/rollup.config.js +70 -0
  103. package/strophejs-1.6.1/src/bosh.js +916 -0
  104. package/strophejs-1.6.1/src/builder.js +239 -0
  105. package/strophejs-1.6.1/src/constants.js +155 -0
  106. package/strophejs-1.6.1/src/core.js +2377 -0
  107. package/strophejs-1.6.1/src/sasl-anon.js +17 -0
  108. package/strophejs-1.6.1/src/sasl-external.js +27 -0
  109. package/strophejs-1.6.1/src/sasl-oauthbearer.js +30 -0
  110. package/strophejs-1.6.1/src/sasl-plain.js +32 -0
  111. package/strophejs-1.6.1/src/sasl-sha1.js +24 -0
  112. package/strophejs-1.6.1/src/sasl-sha256.js +24 -0
  113. package/strophejs-1.6.1/src/sasl-sha384.js +24 -0
  114. package/strophejs-1.6.1/src/sasl-sha512.js +24 -0
  115. package/strophejs-1.6.1/src/sasl-xoauth2.js +27 -0
  116. package/strophejs-1.6.1/src/sasl.js +143 -0
  117. package/strophejs-1.6.1/src/scram.js +182 -0
  118. package/strophejs-1.6.1/src/shared-connection-worker.js +114 -0
  119. package/strophejs-1.6.1/src/shims.js +122 -0
  120. package/strophejs-1.6.1/src/strophe.js +15 -0
  121. package/strophejs-1.6.1/src/utils.js +626 -0
  122. package/strophejs-1.6.1/src/websocket.js +556 -0
  123. package/strophejs-1.6.1/src/worker-websocket.js +149 -0
  124. package/strophejs-1.6.1/tests.js +993 -0
@@ -0,0 +1,17 @@
1
+ import SASLMechanism from './sasl.js';
2
+
3
+ // Building SASL callbacks
4
+
5
+ export default class SASLAnonymous extends SASLMechanism {
6
+
7
+ /** PrivateConstructor: SASLAnonymous
8
+ * SASL ANONYMOUS authentication.
9
+ */
10
+ constructor (mechname='ANONYMOUS', isClientFirst=false, priority=20) {
11
+ super(mechname, isClientFirst, priority);
12
+ }
13
+
14
+ test (connection) { // eslint-disable-line class-methods-use-this
15
+ return connection.authcid === null;
16
+ }
17
+ }
@@ -0,0 +1,27 @@
1
+ import SASLMechanism from './sasl.js';
2
+
3
+ export default class SASLExternal extends SASLMechanism {
4
+
5
+ /** PrivateConstructor: SASLExternal
6
+ * SASL EXTERNAL authentication.
7
+ *
8
+ * The EXTERNAL mechanism allows a client to request the server to use
9
+ * credentials established by means external to the mechanism to
10
+ * authenticate the client. The external means may be, for instance,
11
+ * TLS services.
12
+ */
13
+ constructor (mechname='EXTERNAL', isClientFirst=true, priority=10) {
14
+ super(mechname, isClientFirst, priority);
15
+ }
16
+
17
+ onChallenge (connection) { // eslint-disable-line class-methods-use-this
18
+ /** According to XEP-178, an authzid SHOULD NOT be presented when the
19
+ * authcid contained or implied in the client certificate is the JID (i.e.
20
+ * authzid) with which the user wants to log in as.
21
+ *
22
+ * To NOT send the authzid, the user should therefore set the authcid equal
23
+ * to the JID when instantiating a new Strophe.Connection object.
24
+ */
25
+ return connection.authcid === connection.authzid ? '' : connection.authzid;
26
+ }
27
+ }
@@ -0,0 +1,30 @@
1
+ import SASLMechanism from './sasl.js';
2
+ import utils from './utils';
3
+
4
+ export default class SASLOAuthBearer extends SASLMechanism {
5
+
6
+ /** PrivateConstructor: SASLOAuthBearer
7
+ * SASL OAuth Bearer authentication.
8
+ */
9
+ constructor (mechname='OAUTHBEARER', isClientFirst=true, priority=40) {
10
+ super(mechname, isClientFirst, priority);
11
+ }
12
+
13
+ test (connection) { // eslint-disable-line class-methods-use-this
14
+ return connection.pass !== null;
15
+ }
16
+
17
+ onChallenge (connection) { // eslint-disable-line class-methods-use-this
18
+ let auth_str = 'n,';
19
+ if (connection.authcid !== null) {
20
+ auth_str = auth_str + 'a=' + connection.authzid;
21
+ }
22
+ auth_str = auth_str + ',';
23
+ auth_str = auth_str + "\u0001";
24
+ auth_str = auth_str + 'auth=Bearer ';
25
+ auth_str = auth_str + connection.pass;
26
+ auth_str = auth_str + "\u0001";
27
+ auth_str = auth_str + "\u0001";
28
+ return utils.utf16to8(auth_str);
29
+ }
30
+ }
@@ -0,0 +1,32 @@
1
+ import SASLMechanism from './sasl.js';
2
+ import utils from './utils';
3
+
4
+
5
+ export default class SASLPlain extends SASLMechanism {
6
+
7
+ /** PrivateConstructor: SASLPlain
8
+ * SASL PLAIN authentication.
9
+ */
10
+ constructor (mechname='PLAIN', isClientFirst=true, priority=50) {
11
+ super(mechname, isClientFirst, priority);
12
+ }
13
+
14
+ test (connection) { // eslint-disable-line class-methods-use-this
15
+ return connection.authcid !== null;
16
+ }
17
+
18
+ onChallenge (connection) { // eslint-disable-line class-methods-use-this
19
+ const { authcid, authzid, domain, pass } = connection;
20
+ if (!domain) {
21
+ throw new Error("SASLPlain onChallenge: domain is not defined!");
22
+ }
23
+ // Only include authzid if it differs from authcid.
24
+ // See: https://tools.ietf.org/html/rfc6120#section-6.3.8
25
+ let auth_str = (authzid !== `${authcid}@${domain}`) ? authzid : '';
26
+ auth_str = auth_str + "\u0000";
27
+ auth_str = auth_str + authcid;
28
+ auth_str = auth_str + "\u0000";
29
+ auth_str = auth_str + pass;
30
+ return utils.utf16to8(auth_str);
31
+ }
32
+ }
@@ -0,0 +1,24 @@
1
+ import SASLMechanism from './sasl.js';
2
+ import scram from './scram.js';
3
+
4
+ export default class SASLSHA1 extends SASLMechanism {
5
+
6
+ /** PrivateConstructor: SASLSHA1
7
+ * SASL SCRAM SHA 1 authentication.
8
+ */
9
+ constructor (mechname='SCRAM-SHA-1', isClientFirst=true, priority=60) {
10
+ super(mechname, isClientFirst, priority);
11
+ }
12
+
13
+ test (connection) { // eslint-disable-line class-methods-use-this
14
+ return connection.authcid !== null;
15
+ }
16
+
17
+ async onChallenge (connection, challenge) { // eslint-disable-line class-methods-use-this, require-await
18
+ return scram.scramResponse(connection, challenge, "SHA-1", 160);
19
+ }
20
+
21
+ clientChallenge (connection, test_cnonce) { // eslint-disable-line class-methods-use-this
22
+ return scram.clientChallenge(connection, test_cnonce);
23
+ }
24
+ }
@@ -0,0 +1,24 @@
1
+ import SASLMechanism from './sasl.js';
2
+ import scram from './scram.js';
3
+
4
+ export default class SASLSHA256 extends SASLMechanism {
5
+
6
+ /** PrivateConstructor: SASLSHA256
7
+ * SASL SCRAM SHA 256 authentication.
8
+ */
9
+ constructor (mechname='SCRAM-SHA-256', isClientFirst=true, priority=70) {
10
+ super(mechname, isClientFirst, priority);
11
+ }
12
+
13
+ test (connection) { // eslint-disable-line class-methods-use-this
14
+ return connection.authcid !== null;
15
+ }
16
+
17
+ async onChallenge (connection, challenge) { // eslint-disable-line class-methods-use-this, require-await
18
+ return scram.scramResponse(connection, challenge, "SHA-256", 256);
19
+ }
20
+
21
+ clientChallenge (connection, test_cnonce) { // eslint-disable-line class-methods-use-this
22
+ return scram.clientChallenge(connection, test_cnonce);
23
+ }
24
+ }
@@ -0,0 +1,24 @@
1
+ import SASLMechanism from './sasl.js';
2
+ import scram from './scram.js';
3
+
4
+ export default class SASLSHA384 extends SASLMechanism {
5
+
6
+ /** PrivateConstructor: SASLSHA384
7
+ * SASL SCRAM SHA 384 authentication.
8
+ */
9
+ constructor (mechname='SCRAM-SHA-384', isClientFirst=true, priority=71) {
10
+ super(mechname, isClientFirst, priority);
11
+ }
12
+
13
+ test (connection) { // eslint-disable-line class-methods-use-this
14
+ return connection.authcid !== null;
15
+ }
16
+
17
+ async onChallenge (connection, challenge) { // eslint-disable-line class-methods-use-this, require-await
18
+ return scram.scramResponse(connection, challenge, "SHA-384", 384);
19
+ }
20
+
21
+ clientChallenge (connection, test_cnonce) { // eslint-disable-line class-methods-use-this
22
+ return scram.clientChallenge(connection, test_cnonce);
23
+ }
24
+ }
@@ -0,0 +1,24 @@
1
+ import SASLMechanism from './sasl.js';
2
+ import scram from './scram.js';
3
+
4
+ export default class SASLSHA512 extends SASLMechanism {
5
+
6
+ /** PrivateConstructor: SASLSHA512
7
+ * SASL SCRAM SHA 512 authentication.
8
+ */
9
+ constructor (mechname='SCRAM-SHA-512', isClientFirst=true, priority=72) {
10
+ super(mechname, isClientFirst, priority);
11
+ }
12
+
13
+ test (connection) { // eslint-disable-line class-methods-use-this
14
+ return connection.authcid !== null;
15
+ }
16
+
17
+ async onChallenge (connection, challenge) { // eslint-disable-line class-methods-use-this, require-await
18
+ return scram.scramResponse(connection, challenge, "SHA-512", 512);
19
+ }
20
+
21
+ clientChallenge (connection, test_cnonce) { // eslint-disable-line class-methods-use-this
22
+ return scram.clientChallenge(connection, test_cnonce);
23
+ }
24
+ }
@@ -0,0 +1,27 @@
1
+ import SASLMechanism from './sasl.js';
2
+ import utils from './utils';
3
+
4
+
5
+ export default class SASLXOAuth2 extends SASLMechanism {
6
+
7
+ /** PrivateConstructor: SASLXOAuth2
8
+ * SASL X-OAuth2 authentication.
9
+ */
10
+ constructor (mechname='X-OAUTH2', isClientFirst=true, priority=30) {
11
+ super(mechname, isClientFirst, priority);
12
+ }
13
+
14
+ test (connection) { // eslint-disable-line class-methods-use-this
15
+ return connection.pass !== null;
16
+ }
17
+
18
+ onChallenge (connection) { // eslint-disable-line class-methods-use-this
19
+ let auth_str = '\u0000';
20
+ if (connection.authcid !== null) {
21
+ auth_str = auth_str + connection.authzid;
22
+ }
23
+ auth_str = auth_str + "\u0000";
24
+ auth_str = auth_str + connection.pass;
25
+ return utils.utf16to8(auth_str);
26
+ }
27
+ }
@@ -0,0 +1,143 @@
1
+ /** Class: Strophe.SASLMechanism
2
+ *
3
+ * Encapsulates an SASL authentication mechanism.
4
+ *
5
+ * User code may override the priority for each mechanism or disable it completely.
6
+ * See <priority> for information about changing priority and <test> for informatian on
7
+ * how to disable a mechanism.
8
+ *
9
+ * By default, all mechanisms are enabled and the priorities are
10
+ *
11
+ * SCRAM-SHA-512 - 72
12
+ * SCRAM-SHA-384 - 71
13
+ * SCRAM-SHA-256 - 70
14
+ * SCRAM-SHA-1 - 60
15
+ * PLAIN - 50
16
+ * OAUTHBEARER - 40
17
+ * X-OAUTH2 - 30
18
+ * ANONYMOUS - 20
19
+ * EXTERNAL - 10
20
+ *
21
+ * See: Strophe.Connection.addSupportedSASLMechanisms
22
+ */
23
+ export default class SASLMechanism {
24
+
25
+ /**
26
+ * PrivateConstructor: Strophe.SASLMechanism
27
+ * SASL auth mechanism abstraction.
28
+ *
29
+ * Parameters:
30
+ * (String) name - SASL Mechanism name.
31
+ * (Boolean) isClientFirst - If client should send response first without challenge.
32
+ * (Number) priority - Priority.
33
+ *
34
+ * Returns:
35
+ * A new Strophe.SASLMechanism object.
36
+ */
37
+ constructor (name, isClientFirst, priority) {
38
+ /** PrivateVariable: mechname
39
+ * Mechanism name.
40
+ */
41
+ this.mechname = name;
42
+
43
+ /** PrivateVariable: isClientFirst
44
+ * If client sends response without initial server challenge.
45
+ */
46
+ this.isClientFirst = isClientFirst;
47
+
48
+ /** Variable: priority
49
+ * Determines which <SASLMechanism> is chosen for authentication (Higher is better).
50
+ * Users may override this to prioritize mechanisms differently.
51
+ *
52
+ * Example: (This will cause Strophe to choose the mechanism that the server sent first)
53
+ *
54
+ * > Strophe.SASLPlain.priority = Strophe.SASLSHA1.priority;
55
+ *
56
+ * See <SASL mechanisms> for a list of available mechanisms.
57
+ *
58
+ */
59
+ this.priority = priority;
60
+ }
61
+
62
+ /**
63
+ * Function: test
64
+ * Checks if mechanism able to run.
65
+ * To disable a mechanism, make this return false;
66
+ *
67
+ * To disable plain authentication run
68
+ * > Strophe.SASLPlain.test = function() {
69
+ * > return false;
70
+ * > }
71
+ *
72
+ * See <SASL mechanisms> for a list of available mechanisms.
73
+ *
74
+ * Parameters:
75
+ * (Strophe.Connection) connection - Target Connection.
76
+ *
77
+ * Returns:
78
+ * (Boolean) If mechanism was able to run.
79
+ */
80
+ test () { // eslint-disable-line class-methods-use-this
81
+ return true;
82
+ }
83
+
84
+ /** PrivateFunction: onStart
85
+ * Called before starting mechanism on some connection.
86
+ *
87
+ * Parameters:
88
+ * (Strophe.Connection) connection - Target Connection.
89
+ */
90
+ onStart (connection) {
91
+ this._connection = connection;
92
+ }
93
+
94
+ /** PrivateFunction: onChallenge
95
+ * Called by protocol implementation on incoming challenge.
96
+ *
97
+ * By deafult, if the client is expected to send data first (isClientFirst === true),
98
+ * this method is called with `challenge` as null on the first call,
99
+ * unless `clientChallenge` is overridden in the relevant subclass.
100
+ *
101
+ * Parameters:
102
+ * (Strophe.Connection) connection - Target Connection.
103
+ * (String) challenge - current challenge to handle.
104
+ *
105
+ * Returns:
106
+ * (String) Mechanism response.
107
+ */
108
+ onChallenge (connection, challenge) { // eslint-disable-line
109
+ throw new Error("You should implement challenge handling!");
110
+ }
111
+
112
+ /** PrivateFunction: clientChallenge
113
+ * Called by the protocol implementation if the client is expected to send
114
+ * data first in the authentication exchange (i.e. isClientFirst === true).
115
+ *
116
+ * Parameters:
117
+ * (Strophe.Connection) connection - Target Connection.
118
+ *
119
+ * Returns:
120
+ * (String) Mechanism response.
121
+ */
122
+ clientChallenge (connection) {
123
+ if (!this.isClientFirst) {
124
+ throw new Error("clientChallenge should not be called if isClientFirst is false!");
125
+ }
126
+ return this.onChallenge(connection);
127
+ }
128
+
129
+ /** PrivateFunction: onFailure
130
+ * Protocol informs mechanism implementation about SASL failure.
131
+ */
132
+ onFailure () {
133
+ this._connection = null;
134
+ }
135
+
136
+ /** PrivateFunction: onSuccess
137
+ * Protocol informs mechanism implementation about SASL success.
138
+ */
139
+ onSuccess () {
140
+ this._connection = null;
141
+ }
142
+
143
+ }
@@ -0,0 +1,182 @@
1
+ import utils from './utils';
2
+ import { Strophe } from './core.js';
3
+
4
+ async function scramClientProof( authMessage, clientKey, hashName ) {
5
+ const storedKey = await window.crypto.subtle.importKey(
6
+ "raw",
7
+ await window.crypto.subtle.digest(hashName, clientKey),
8
+ { "name": "HMAC", "hash": hashName },
9
+ false,
10
+ ["sign"]
11
+ );
12
+ const clientSignature = await window.crypto.subtle.sign("HMAC", storedKey, utils.stringToArrayBuf(authMessage));
13
+
14
+ return utils.xorArrayBuffers(clientKey, clientSignature);
15
+ }
16
+
17
+ /* This function parses the information in a SASL SCRAM challenge response,
18
+ * into an object of the form
19
+ * { nonce: String,
20
+ * salt: ArrayBuffer,
21
+ * iter: Int
22
+ * }
23
+ * Returns undefined on failure.
24
+ */
25
+ function scramParseChallenge ( challenge ) {
26
+ let nonce, salt, iter;
27
+ const attribMatch = /([a-z]+)=([^,]+)(,|$)/;
28
+ while (challenge.match(attribMatch)) {
29
+ const matches = challenge.match(attribMatch);
30
+ challenge = challenge.replace(matches[0], "");
31
+ switch (matches[1]) {
32
+ case "r":
33
+ nonce = matches[2];
34
+ break;
35
+ case "s":
36
+ salt = utils.base64ToArrayBuf(matches[2]);
37
+ break;
38
+ case "i":
39
+ iter = parseInt(matches[2], 10);
40
+ break;
41
+ default: return undefined;
42
+ }
43
+ }
44
+
45
+ // Consider iteration counts less than 4096 insecure, as reccommended by
46
+ // RFC 5802
47
+ if (isNaN(iter) || iter < 4096) {
48
+ Strophe.warn("Failing SCRAM authentication because server supplied iteration count < 4096.");
49
+ return undefined;
50
+ }
51
+
52
+ if (!salt) {
53
+ Strophe.warn("Failing SCRAM authentication because server supplied incorrect salt.");
54
+ return undefined;
55
+ }
56
+
57
+ return { "nonce": nonce, "salt": salt, "iter": iter };
58
+
59
+ }
60
+
61
+ /* Derive the client and server keys given a string password,
62
+ * a hash name, and a bit length.
63
+ * Returns an object of the following form:
64
+ * { ck: ArrayBuffer, the client key
65
+ * sk: ArrayBuffer, the server key
66
+ * }
67
+ */
68
+ async function scramDeriveKeys ( password, salt, iter, hashName, hashBits ) {
69
+ const saltedPasswordBits = await window.crypto.subtle.deriveBits(
70
+ { "name": "PBKDF2", "salt": salt, "iterations": iter, "hash": { "name": hashName } },
71
+ await window.crypto.subtle.importKey("raw", utils.stringToArrayBuf(password), "PBKDF2", false, ["deriveBits"]),
72
+ hashBits
73
+ );
74
+ const saltedPassword = await window.crypto.subtle.importKey(
75
+ "raw",
76
+ saltedPasswordBits,
77
+ { "name": "HMAC", "hash": hashName },
78
+ false,
79
+ ["sign"]
80
+ );
81
+
82
+ return { "ck": await window.crypto.subtle.sign("HMAC", saltedPassword, utils.stringToArrayBuf("Client Key")),
83
+ "sk": await window.crypto.subtle.sign("HMAC", saltedPassword, utils.stringToArrayBuf("Server Key"))
84
+ }
85
+ }
86
+
87
+ async function scramServerSign ( authMessage, sk, hashName ) {
88
+ const serverKey = await window.crypto.subtle.importKey(
89
+ "raw",
90
+ sk,
91
+ { "name": "HMAC", "hash": hashName },
92
+ false,
93
+ ["sign"]
94
+ );
95
+
96
+ return window.crypto.subtle.sign("HMAC", serverKey, utils.stringToArrayBuf(authMessage));
97
+ }
98
+
99
+ // Generate an ASCII nonce (not containing the ',' character)
100
+ function generate_cnonce () {
101
+ // generate 16 random bytes of nonce, base64 encoded
102
+ const bytes = new Uint8Array(16);
103
+ return utils.arrayBufToBase64(crypto.getRandomValues(bytes).buffer);
104
+ }
105
+
106
+ const scram = {
107
+
108
+ /* On success, sets
109
+ * connection_sasl_data["server-signature"]
110
+ * and
111
+ * connection._sasl_data.keys
112
+ *
113
+ * The server signature should be verified after this function completes..
114
+ *
115
+ * On failure, returns connection._sasl_failure_cb();
116
+ */
117
+ async scramResponse ( connection, challenge, hashName, hashBits ) {
118
+ const cnonce = connection._sasl_data.cnonce;
119
+ const challengeData = scramParseChallenge(challenge);
120
+
121
+ // The RFC requires that we verify the (server) nonce has the client
122
+ // nonce as an initial substring.
123
+ if (!challengeData && challengeData?.nonce.slice(0, cnonce.length) !== cnonce) {
124
+ Strophe.warn("Failing SCRAM authentication because server supplied incorrect nonce.");
125
+ connection._sasl_data = {};
126
+ return connection._sasl_failure_cb();
127
+ }
128
+
129
+ let clientKey, serverKey;
130
+
131
+ // Either restore the client key and server key passed in, or derive new ones
132
+ if ( connection.pass?.name === hashName &&
133
+ connection.pass?.salt === utils.arrayBufToBase64(challengeData.salt) &&
134
+ connection.pass?.iter === challengeData.iter) {
135
+
136
+ clientKey = utils.base64ToArrayBuf(connection.pass.ck);
137
+ serverKey = utils.base64ToArrayBuf(connection.pass.sk);
138
+ } else if (typeof connection.pass === "string" || connection.pass instanceof String) {
139
+ const keys = await scramDeriveKeys(
140
+ connection.pass,
141
+ challengeData.salt,
142
+ challengeData.iter,
143
+ hashName,
144
+ hashBits);
145
+ clientKey = keys.ck;
146
+ serverKey = keys.sk;
147
+ } else {
148
+ return connection._sasl_failure_cb();
149
+ }
150
+
151
+ const clientFirstMessageBare = connection._sasl_data["client-first-message-bare"];
152
+ const serverFirstMessage = challenge;
153
+ const clientFinalMessageBare = `c=biws,r=${challengeData.nonce}`;
154
+
155
+ const authMessage = `${clientFirstMessageBare},${serverFirstMessage},${clientFinalMessageBare}`;
156
+
157
+ const clientProof = await scramClientProof(authMessage, clientKey, hashName);
158
+ const serverSignature = await scramServerSign(authMessage, serverKey, hashName);
159
+
160
+ connection._sasl_data["server-signature"] = utils.arrayBufToBase64(serverSignature);
161
+ connection._sasl_data.keys =
162
+ { "name": hashName,
163
+ "iter": challengeData.iter,
164
+ "salt": utils.arrayBufToBase64(challengeData.salt),
165
+ "ck": utils.arrayBufToBase64(clientKey),
166
+ "sk": utils.arrayBufToBase64(serverKey)
167
+ };
168
+
169
+ return `${clientFinalMessageBare},p=${utils.arrayBufToBase64(clientProof)}`;
170
+ },
171
+
172
+ // Returns a string containing the client first message
173
+ clientChallenge ( connection, test_cnonce ) {
174
+ const cnonce = test_cnonce || generate_cnonce();
175
+ const client_first_message_bare = `n=${connection.authcid},r=${cnonce}`;
176
+ connection._sasl_data.cnonce = cnonce;
177
+ connection._sasl_data["client-first-message-bare"] = client_first_message_bare;
178
+ return `n,,${client_first_message_bare}`;
179
+ }
180
+ }
181
+
182
+ export { scram as default };
@@ -0,0 +1,114 @@
1
+ let manager;
2
+
3
+
4
+ const Status = {
5
+ ERROR: 0,
6
+ CONNECTING: 1,
7
+ CONNFAIL: 2,
8
+ AUTHENTICATING: 3,
9
+ AUTHFAIL: 4,
10
+ CONNECTED: 5,
11
+ DISCONNECTED: 6,
12
+ DISCONNECTING: 7,
13
+ ATTACHED: 8,
14
+ REDIRECT: 9,
15
+ CONNTIMEOUT: 10,
16
+ BINDREQUIRED: 11,
17
+ ATTACHFAIL: 12
18
+ }
19
+
20
+
21
+ /** Class: ConnectionManager
22
+ *
23
+ * Manages the shared websocket connection as well as the ports of the
24
+ * connected tabs.
25
+ */
26
+ class ConnectionManager {
27
+
28
+ constructor () {
29
+ this.ports = [];
30
+ }
31
+
32
+ addPort (port) {
33
+ this.ports.push(port);
34
+ port.addEventListener('message', e => {
35
+ const method = e.data[0];
36
+ try {
37
+ this[method](e.data.splice(1))
38
+ } catch (e) {
39
+ console?.error(e);
40
+ }
41
+ });
42
+ port.start();
43
+ }
44
+
45
+ _connect (data) {
46
+ this.jid = data[1];
47
+ this._closeSocket();
48
+ this.socket = new WebSocket(data[0], "xmpp");
49
+ this.socket.onopen = () => this._onOpen();
50
+ this.socket.onerror = (e) => this._onError(e);
51
+ this.socket.onclose = (e) => this._onClose(e);
52
+ this.socket.onmessage = (message) => this._onMessage(message);
53
+ }
54
+
55
+ _attach () {
56
+ if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {
57
+ this.ports.forEach(p => p.postMessage(['_attachCallback', Status.ATTACHED, this.jid]));
58
+ } else {
59
+ this.ports.forEach(p => p.postMessage(['_attachCallback', Status.ATTACHFAIL]));
60
+ }
61
+ }
62
+
63
+ send (str) {
64
+ this.socket.send(str);
65
+ }
66
+
67
+ close (str) {
68
+ if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {
69
+ try {
70
+ this.socket.send(str);
71
+ } catch (e) {
72
+ this.ports.forEach(p => p.postMessage(['log', 'error', e]));
73
+ this.ports.forEach(p => p.postMessage(
74
+ ['log', 'error', "Couldn't send <close /> tag."]));
75
+ }
76
+ }
77
+ }
78
+
79
+ _onOpen () {
80
+ this.ports.forEach(p => p.postMessage(['_onOpen']));
81
+ }
82
+
83
+ _onClose (e) {
84
+ this.ports.forEach(p => p.postMessage(['_onClose', e.reason]));
85
+ }
86
+
87
+ _onMessage (message) {
88
+ const o = { 'data': message.data }
89
+ this.ports.forEach(p => p.postMessage(['_onMessage', o]));
90
+ }
91
+
92
+ _onError (error) {
93
+ this.ports.forEach(p => p.postMessage(['_onError', error.reason]));
94
+ }
95
+
96
+ _closeSocket () {
97
+ if (this.socket) {
98
+ try {
99
+ this.socket.onclose = null;
100
+ this.socket.onerror = null;
101
+ this.socket.onmessage = null;
102
+ this.socket.close();
103
+ } catch (e) {
104
+ this.ports.forEach(p => p.postMessage(['log', 'error', e]));
105
+ }
106
+ }
107
+ this.socket = null;
108
+ }
109
+ }
110
+
111
+ onconnect = function (e) { // eslint-disable-line no-undef
112
+ manager = manager || new ConnectionManager();
113
+ manager.addPort(e.ports[0]);
114
+ }