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.
- package/LICENSE +330 -201
- package/README.md +2 -2
- package/package.json +1 -2
- package/quickblox.js +19389 -21772
- package/quickblox.min.js +1 -1
- package/src/libs/strophe/strophe.common.js +6657 -0
- package/src/libs/strophe/strophe.esm.js +6649 -0
- package/src/libs/strophe/strophe.umd.js +6862 -0
- package/src/libs/strophe/strophe.umd.min.js +1 -0
- package/src/modules/chat/qbChat.js +131 -11
- package/src/modules/webrtc/qbWebRTCSignalingProcessor.js +2 -1
- package/src/modules/webrtc/qbWebRTCSignalingProvider.js +2 -1
- package/src/qbConfig.js +2 -2
- package/src/qbProxy.js +1 -1
- package/src/qbStrophe.js +2 -6
- package/strophejs-1.4.0/.eslintrc.json +264 -0
- package/strophejs-1.4.0/.gitattributes +1 -0
- package/strophejs-1.4.0/CHANGELOG.md +250 -0
- package/strophejs-1.4.0/LICENSE.txt +19 -0
- package/strophejs-1.4.0/Makefile +92 -0
- package/strophejs-1.4.0/README.md +45 -0
- package/strophejs-1.4.0/RELEASE_CHECKLIST.md +16 -0
- package/strophejs-1.4.0/contrib/discojs/README.txt +42 -0
- package/strophejs-1.4.0/contrib/discojs/css/disco.css +16 -0
- package/strophejs-1.4.0/contrib/discojs/index.html +47 -0
- package/strophejs-1.4.0/contrib/discojs/punjab.tac +18 -0
- package/strophejs-1.4.0/contrib/discojs/scripts/basic.js +102 -0
- package/strophejs-1.4.0/contrib/discojs/scripts/disco.js +60 -0
- package/strophejs-1.4.0/docs.css +797 -0
- package/strophejs-1.4.0/examples/amd.html +21 -0
- package/strophejs-1.4.0/examples/attach/README +37 -0
- package/strophejs-1.4.0/examples/attach/__init__.py +0 -0
- package/strophejs-1.4.0/examples/attach/attacher/__init__.py +0 -0
- package/strophejs-1.4.0/examples/attach/attacher/views.py +18 -0
- package/strophejs-1.4.0/examples/attach/boshclient.py +158 -0
- package/strophejs-1.4.0/examples/attach/manage.py +11 -0
- package/strophejs-1.4.0/examples/attach/settings.py +85 -0
- package/strophejs-1.4.0/examples/attach/templates/attacher/index.html +88 -0
- package/strophejs-1.4.0/examples/attach/urls.py +19 -0
- package/strophejs-1.4.0/examples/basic.html +23 -0
- package/strophejs-1.4.0/examples/basic.js +73 -0
- package/strophejs-1.4.0/examples/echobot.html +25 -0
- package/strophejs-1.4.0/examples/echobot.js +79 -0
- package/strophejs-1.4.0/examples/main.js +59 -0
- package/strophejs-1.4.0/examples/prebind.html +39 -0
- package/strophejs-1.4.0/examples/prebind.js +103 -0
- package/strophejs-1.4.0/examples/restore.html +24 -0
- package/strophejs-1.4.0/examples/restore.js +71 -0
- package/strophejs-1.4.0/package-lock.json +8631 -0
- package/strophejs-1.4.0/package.json +84 -0
- package/strophejs-1.4.0/rollup.config.js +76 -0
- package/strophejs-1.4.0/src/bosh.js +916 -0
- package/strophejs-1.4.0/src/core.js +3530 -0
- package/strophejs-1.4.0/src/md5.js +204 -0
- package/strophejs-1.4.0/src/sha1.js +172 -0
- package/strophejs-1.4.0/src/shared-connection-worker.js +114 -0
- package/strophejs-1.4.0/src/shims.js +123 -0
- package/strophejs-1.4.0/src/strophe.js +14 -0
- package/strophejs-1.4.0/src/utils.js +63 -0
- package/strophejs-1.4.0/src/websocket.js +557 -0
- package/strophejs-1.4.0/src/worker-websocket.js +150 -0
- package/strophejs-1.4.0/tests/index.html +21 -0
- package/strophejs-1.4.0/tests/main.js +49 -0
- package/strophejs-1.4.0/tests/tests.js +929 -0
- package/strophejs-1.6.1/.eslintrc.json +264 -0
- package/strophejs-1.6.1/.gitattributes +1 -0
- package/strophejs-1.6.1/.nvmrc +1 -0
- package/strophejs-1.6.1/CHANGELOG.md +288 -0
- package/strophejs-1.6.1/LICENSE.txt +19 -0
- package/strophejs-1.6.1/Makefile +92 -0
- package/strophejs-1.6.1/README.md +46 -0
- package/strophejs-1.6.1/RELEASE_CHECKLIST.md +18 -0
- package/strophejs-1.6.1/babel.config.json +10 -0
- package/strophejs-1.6.1/contrib/discojs/README.txt +42 -0
- package/strophejs-1.6.1/contrib/discojs/css/disco.css +16 -0
- package/strophejs-1.6.1/contrib/discojs/index.html +47 -0
- package/strophejs-1.6.1/contrib/discojs/punjab.tac +18 -0
- package/strophejs-1.6.1/contrib/discojs/scripts/basic.js +102 -0
- package/strophejs-1.6.1/contrib/discojs/scripts/disco.js +60 -0
- package/strophejs-1.6.1/docs.css +797 -0
- package/strophejs-1.6.1/examples/amd.html +21 -0
- package/strophejs-1.6.1/examples/attach/README +37 -0
- package/strophejs-1.6.1/examples/attach/__init__.py +0 -0
- package/strophejs-1.6.1/examples/attach/attacher/__init__.py +0 -0
- package/strophejs-1.6.1/examples/attach/attacher/views.py +18 -0
- package/strophejs-1.6.1/examples/attach/boshclient.py +158 -0
- package/strophejs-1.6.1/examples/attach/manage.py +11 -0
- package/strophejs-1.6.1/examples/attach/settings.py +85 -0
- package/strophejs-1.6.1/examples/attach/templates/attacher/index.html +88 -0
- package/strophejs-1.6.1/examples/attach/urls.py +19 -0
- package/strophejs-1.6.1/examples/basic.html +23 -0
- package/strophejs-1.6.1/examples/basic.js +73 -0
- package/strophejs-1.6.1/examples/echobot.html +25 -0
- package/strophejs-1.6.1/examples/echobot.js +79 -0
- package/strophejs-1.6.1/examples/main.js +59 -0
- package/strophejs-1.6.1/examples/prebind.html +39 -0
- package/strophejs-1.6.1/examples/prebind.js +103 -0
- package/strophejs-1.6.1/examples/restore.html +24 -0
- package/strophejs-1.6.1/examples/restore.js +71 -0
- package/strophejs-1.6.1/package-lock.json +18461 -0
- package/strophejs-1.6.1/package.json +87 -0
- package/strophejs-1.6.1/rollup.config.js +70 -0
- package/strophejs-1.6.1/src/bosh.js +916 -0
- package/strophejs-1.6.1/src/builder.js +239 -0
- package/strophejs-1.6.1/src/constants.js +155 -0
- package/strophejs-1.6.1/src/core.js +2377 -0
- package/strophejs-1.6.1/src/sasl-anon.js +17 -0
- package/strophejs-1.6.1/src/sasl-external.js +27 -0
- package/strophejs-1.6.1/src/sasl-oauthbearer.js +30 -0
- package/strophejs-1.6.1/src/sasl-plain.js +32 -0
- package/strophejs-1.6.1/src/sasl-sha1.js +24 -0
- package/strophejs-1.6.1/src/sasl-sha256.js +24 -0
- package/strophejs-1.6.1/src/sasl-sha384.js +24 -0
- package/strophejs-1.6.1/src/sasl-sha512.js +24 -0
- package/strophejs-1.6.1/src/sasl-xoauth2.js +27 -0
- package/strophejs-1.6.1/src/sasl.js +143 -0
- package/strophejs-1.6.1/src/scram.js +182 -0
- package/strophejs-1.6.1/src/shared-connection-worker.js +114 -0
- package/strophejs-1.6.1/src/shims.js +122 -0
- package/strophejs-1.6.1/src/strophe.js +15 -0
- package/strophejs-1.6.1/src/utils.js +626 -0
- package/strophejs-1.6.1/src/websocket.js +556 -0
- package/strophejs-1.6.1/src/worker-websocket.js +149 -0
- 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
|
+
}
|