Welcome to JavaScript XMPP Client’s documentation!¶
JSXC is a free XMPP client licensed under the MIT license.
This version of the documentation covering JSXC 4.0.0-alpha has been rendered at: Aug 25, 2021
Getting Started¶
Requirements¶
Obviously you need a running web server and a XMPP server with BOSH support.
Web server¶
Apache¶
If not already done, install apache on your Debian-based distribution:
sudo apt install apache2
Enable the apache proxy module:
sudo a2enmod proxy
sudo a2enmod proxy_http
Add the proxy definition to your vhost configuration of your host-application
server (e.g. /etc/apache/sites-available/default
):
ProxyPass /http-bind/ http://localhost:5280/http-bind/
ProxyPassReverse /http-bind/ http://localhost:5280/http-bind/
Reload apache configuration:
sudo service apache2 reload
Finished!
Lighttpd¶
Enable the mod_proxy
module and add the proxy definition in
/etc/lighttpd/lighttpd.conf
:
server.modules += ( "mod_proxy" )
proxy.server = (
"/http-bind" => (
( "host" => "127.0.0.1", "port" => 5280 )
)
)
Here is an alternative example of a vhost config.
In the lighttpd.conf
enable the mod_proxy module:
server.modules = (
...
"mod_proxy"
...
)
...
# include all files that are under vhosts
include_shell "cat /etc/lighttpd/vhosts/*.conf"
and in vhosts/cloud.myserver.com.conf
:
$HTTP["host"] == "cloud.myserver.com" {
...
proxy.server = (
"/http-bind" => (
( "host" => "127.0.0.1", "port" => 5280 )
)
)
}
Nginx¶
Enable the proxy pass in your Nginx vhost config:
server {
...
location /http-bind {
proxy_pass http://127.0.0.1:5280;
proxy_set_header Host $host;
tcp_nodelay on;
}
}
Installation¶
JSXC for Nextcloud¶
Warning
JSXC assumes that you are using the same credentials for your Nextcloud and XMPP server.
Requirements¶
TODO
Get it¶
Go to your app store and enable the JavaScript XMPP Client.
Configure it¶
Go to the Nextcloud admin page:
- BOSH URL
- The URL to your bosh server (e.g.
/http-bind/
). Please be aware of the same-origin-policy. If your XMPP server doesn’t reside on the same host as your OwnCloud, use the Apache ProxyRequest as described in our prepare Apache guide. - XMPP domain
- The domain of your Jabber ID.
- XMPP resource
- The resource of your JID. If you leaf this field blank a random resource is generated.
- TURN url
- The url to your TURN server. You get a free account on http://numb.viagenie.ca
- TURN username
- If no username is set, the TURN REST API is used.
- TURN credential
- If no credential is set, the TURN REST API is used.</dd>
- TURN secret
- Secret for TURN REST API.
- TURN ttl
- Lifetime of credentials.
Internal JSXC XMPP server¶
OJSXC implements a minimal XMPP server, just enough such that JSXC works. It is meant as a starting point, as long as you only run JSXC on Nextcloud. As soon as you require more features (external clients, server-to-server communications, …) you should install a full-fledged XMPP server (they are pretty easy to install).
JSXC for WordPress¶
In addition to the WordPress installation you need a running XMPP server with BOSH support. Next you have to configure your XMPP server, maybe activate your BOSH module and to make sure, that your BOSH Server is reachable by your website. If your XMPP server supports CORS everything should be fine.
Install web server, xmpp server, (bosh server)
Download and extract [jsxc](https://github.com/jsxc/jsxc/releases) to a folder of your choice inside of your WordPress theme folder (e.g. /data/mydomain.com/webroot/wp-content/themes/mytheme/jsxc).
Create a
jsxc_client.js
file in your scripts directory (e.g. /data/mydomain.com/webroot/wp-content/themes/mytheme/js) and insert the following code into it:$(function($) { jsxc.init({ loginForm: { form: '#page-login-form', jid: '#page-user-login', pass: '#page-user-pass' }, logoutElement: $('#logout-element'), root: '../jsxc/', displayRosterMinimized: function() { return true; }, xmpp: { url: 'http://YOUR_XMPP_SERVER.com:7070/http-bind/', domain: 'YOUR_DOMAIN', resource: 'jsxc' } }); });
Replace
YOUR_DOMAIN
with the domain of you XMPP server andhttp://YOUR_XMPP_SERVER.com:7070/http-bind/
with a correct URL of your BOSH server. Also replace#page-login-form
,#page-user-login
,#page-user-pass
and#logout-element
with correct id’s of your site.Create a
jsxc-custom.css
file inside of the styles directory of your site (e.g./data/mydomain.com/webroot/wp-content/themes/mytheme/css/
).Insert the following lines of code into some shared page (e.g.
header.php
):<link href="<?php echo get_template_directory_uri(); ?>/jsxc/css/jquery-ui.min.css" media="all" rel="stylesheet" type="text/css" /> <link href="<?php echo get_template_directory_uri(); ?>/jsxc/css/jsxc.css" media="all" rel="stylesheet" type="text/css" /> <link href="<?php echo get_template_directory_uri(); ?>/jsxc/css/jsxc.webrtc.css" media="all" rel="stylesheet" type="text/css" /> <link href="<?php echo get_template_directory_uri(); ?>/css/jsxc-custom.css" media="all" rel="stylesheet" type="text/css" /> <script src="<?php echo get_template_directory_uri(); ?>/jsxc/lib/jquery.min.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/jsxc/lib/jquery.ui.min.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/jsxc/lib/jquery.colorbox-min.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/jsxc/lib/jquery.slimscroll.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/jsxc/lib/jquery.fullscreen.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/jsxc/lib/jsxc.dep.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/jsxc/jsxc.min.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/js/jsxc_client.js"></script>
Verify that jquery is not loaded twice, otherwise the client will not work correctly.
6. Open the main page of your site and notice the jsxc is working.
7. Investigate the CSS styles of jsxc and overwrite the required styles in jsxc-custom.css
to match your site’s UI.
JSXC for Ilias¶
Warning
The Ilias version of JSXC is currently unmaintained.
Get the code¶
Packed version¶
Download the latest version from releases <https://github.com/jsxc/jsxc.ilias/releases>
and extract it to ILIAS_DIR/Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/
.
Development version¶
cd ILIAS_DIR/Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/ git clone https://github.com/sualko/jsxc.ilias ijsxc cd ijsxc git submodule update –init –recursive
Configuration¶
Rename config.inc.php.sample
to config.inc.php
and adjust the values for XMPP server,
BOSH url and XMPP domain and the values for WebRTC.
JSXC for SOGo¶
Warning
The SOGo version of JSXC is currently unmaintained.
Get the code¶
Packed version¶
Download the latest version from releases
and extract it to /usr/lib/GNUstep/SOGo/WebServerResources/
.
Development version¶
cd /opt
git clone https://github.com/jsxc/jsxc.sogo sjsxc
cd sjsxc
git submodule update --init --recursive
ln -s /opt/sjsxc /usr/lib/GNUstep/SOGo/WebServerResources/
JSXC Configuration¶
It is good to first make sure you can connect and established XMPP communications before configuring the WebRTC part (which should anyway work most of the time right off with default configuration).
Rename sjsxc/js/sjsxc.config.sample.js
to sjsxc/js/sjsxc.config.js
and adjust the values for xmpp server, bosh url and xmpp domain.
Example¶
Here below is an example of a working config file with few options although sufficient to get JSXC plugin to connect to your XMPP server.
File sjsxc.config.js
:
/**
* feel free to browse through ./jsxc/src/jsxc.options.js to see possible configurations options
**/
var sjsxc = {};
sjsxc.config = {
/** enable chat by default? */
enable: true,
/** JSXC options. */
jsxc: {
xmpp: {
/** url to bosh server binding. Adapt port to the one you declared in your XMPP server's config */
url: 'https://xmpp.example.com:7443/http-bind/',
/** domain part of your jid */
domain: 'example.com',
/** which resource should be used? Blank, means random. */
resource: '',
/** Allow user to overwrite xmpp settings? */
overwrite: true,
/** Should chat start on login? */
onlogin: true
}
}
};
Note
it might be a good idea to use a reverse proxy for reaching the BOSH server (url parameter then becoming https://xmpp.example.com/http-bind/, otherwise tight-up networks would prevent the user to connect to XMPP’s port.
SOGo configuration¶
Add SOGoUIAdditionalJSFiles
to your sogo config (/etc/sogo/sogo.conf
).
Packed version¶
{
[...]
SOGoUIAdditionalJSFiles = (
"sjsxc/js/lib/jquery.min.js", // only SOGo v3
"sjsxc/js/lib/jquery.ui.min.js",
"sjsxc/js/jsxc/lib/jquery.slimscroll.js",
"sjsxc/js/jsxc/lib/jquery.fullscreen.js",
"sjsxc/js/jsxc/lib/jsxc.dep.min.js",
"sjsxc/js/jsxc/jsxc.min.js",
"sjsxc/js/sjsxc.config.js",
"sjsxc/js/sjsxc.js"
);
[...]
}
Development version¶
{
[...]
SOGoUIAdditionalJSFiles = (
"sjsxc/js/lib/jquery.min.js", // only SOGo v3
"sjsxc/js/lib/jquery.ui.min.js",
"sjsxc/js/jsxc/dev/lib/jquery.slimscroll.js",
"sjsxc/js/jsxc/dev/lib/jquery.fullscreen.js",
"sjsxc/js/jsxc/dev/lib/jsxc.dep.js",
"sjsxc/js/jsxc/dev/jsxc.js",
"sjsxc/js/sjsxc.config.js",
"sjsxc/js/sjsxc.js"
);
[...]
}
Restart sogo service¶
sudo service sogo restart
Debug¶
First off, make sure your BOSH server is accessible, and that the certificate is valid for HTTPS. One way to do that is prepare a generic test file (_testBosh.txt_) that you’ll call via curl command :
Content of the file testBosh.txt
:
<body content='text/xml; charset=utf-8'
from='user@localhost'
hold='1'
rid='1573741820'
to='localhost'
wait='60'
xml:lang='en'
xmpp:version='1.0'
xmlns='http://jabber.org/protocol/httpbind' xmlns:xmpp='urn:xmpp:xbosh'/>
Save the file locally on your computer and run:
curl -X POST -d@testBosh.txt https://xmpp.example.com:7443/http-bind/
If you get this kind of output, you are good to go as far as BOSH access to XMPP server is concerned, with valid certificate for HTTPS access.
<body xmlns="http://jabber.org/protocol/httpbind" xmlns:stream="http://etherx.jabber.org/streams"
from="example.com" authid="55j3i8xlx2" sid="55j3i8xlx2" secure="true"
requests="2" inactivity="30" polling="5" wait="60">
<stream:features>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>PLAIN</mechanism>
</mechanisms>
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
<session xmlns="urn:ietf:params:xml:ns:xmpp-session">
<optional/>
</session>
</stream:features>
</body>
Finally, JSXC core being all about Javascript, you need to open your browser console (Ctrl-Shift-i on Firefox) and filter all JS information.
Next¶
Once JSXC is well anchored in your SOGo interface and you have a fully functionnal OTR-capable integrated chat, it is now time to test and use video chat.
Overview¶
- Install web server, xmpp server, (bosh server)
- Add jQuery to your site
- Download and extract jsxc (you have to use the tar file) to a folder of your choice (e.g.
jsxc.example
) - Create two folders in your directory
css
andjs
- Create a file in each folder:
jsxc.example.css
incss
andjsxc.example.js
injs
- Adjust permissions
Your folder structure should now look like:
- jsxc.example/
- jsxc/
- css/
- jsxc.example.css
- js/
- jsxc.example.js
Include¶
Now include all these files in your template:
<!-- Javascript -->
<script src="/jquery.min.js"></script>
<script src="jsxc.example/jsxc/jsxc.bundle.js"></script>
<script src="jsxc.example/js/jsxc.example.js"></script>
<!-- Stylesheets -->
<link href="jsxc.example/jsxc/styles/jsxc.bundle.css" media="all" rel="stylesheet" type="text/css" />
<link href="jsxc.example/css/jsxc.example.css" media="all" rel="stylesheet" type="text/css" />
Configure¶
Add the following lines to our jsxc.example.js
:
$(function() {
let jsxc = new JSXC({
loadConnectionOptions: function(username, password) {
return Promise.resolve({
xmpp: {
url: '/http-bind/',
domain: 'localhost',
}
});
}
});
let formElement = $('#form');
let usernameElement = $('#username');
let passwordElement = $('#password');
jsxc.watchForm(formElement, usernameElement, passwordElement);
});
Adjust the values according to your application.
Customize style¶
TODO
Enjoy¶
Now you should be ready to go.
Contributor Guid¶
There are plenty of ways to give something back to the open source community. Following you find a couple of them for JSXC and no matter which you choose, we appreciate every help.
Report a bug¶
You found a bug in a stable release of JSXC? Please open a new issue for it on our issue tracker. You want to minimize the number of bugs in stable releases? Just watch our repository or follow us on twitter to receive notifications about new prereleases.
Please provide the following points in your issue: - Which jsxc version number do you use? - In which system do you use jsxc? (e.g. nextcloud, sogo, …) - Can you reproduce your issue? If yes, how? - Which browser and browser version do you use? - Do you have any browser plugins enabled? - Do you see any errors in your javascript console (ctrl+shift+I)? - Which messages appear in your javascript console if you enable debugging? - Do you have any related entries in your XMPP server log or your host system (e.g. nextcloud, sogo, …)?
Contribute code¶
You find detailed information in our developer notes, but the following steps describes the general process.
- Fork the corresponding repository
- Create a local branch for your fix
- Commit your changes and push your created branch to your fork
- Open a new pull request into our master branch
A good way to get familiar with JSXC to work on a starter issue.
Translate JSXC into your language¶
JSXC is currently translated into 13 languages and we are always looking for new translators, which add new or complete existing languages. Interested? Request an invitation.

Announce¶
You like JSXC and you have a blog? It would be great if you could write a small post about JSXC.
API¶
Note
We use a Typescript-like syntax to describe our API. For example a following question mark means that this argument or property is optional.
General¶
<constructor> JSXC(options?)¶
You have to initialize JSXC with some options so it can learn about your environment. If you have already some established sessions, those will be restored.
Arguments¶
options.appName?
(string)Name of container application (e.g. Nextcloud or SOGo).
Default:
"web applications"
options.lang?
(string)Default language.
Default:
"en"
options.autoLang?
(boolean)Auto language detection.
Default:
true
options.rosterAppend?
(string)Query string for element which should contain your contact list.
Default:
"body"
options.rosterVisibility?
(“shown”|”hidden”)Default roster visibility.
Default:
"shown"
options.hideOfflineContacts?
(boolean)Set to true if you want to hide offline contacts.
Default:
false
options.loadOptions?
(jid: string, password: string) => Promise<{[id: string]: {[key: string]: any}}>If you store option changes with
options.onOptionChange
you probably want to restore them on the next login. Just return an object with all id’s and the corresponding values.Default:
undefined
options.loadConnectionOptions?
(username: string, password: string) => Promise<ISettings>This option can provide connection options for every form login (form watcher, login dialog).
Default:
undefined
options.onOptionChange?
(id: string, key: string, value: any, exportId: () => any) => voidThis function is called every time the user changes a option.
Default:
undefined
options.getUsers?
(search: string) => Promise<{[uid: string]: string}>If you like to provide auto suggestions if the user is adding a contact, you should add this function. Key has be a JID or UID and value a display name.
Default:
undefined
options.RTCPeerConfig.ttl?
(number)Time-to-live for config from url.
Default:
3600
options.RTCPeerConfig.iceServers?
(array)ICE servers like defined in http://www.w3.org/TR/webrtc/#idl-def-RTCIceServer;
Default:
[{ urls: 'stun:stun.stunprotocol.org' }]
options.onlineHelp?
(string)Default:
http://www.jsxc.org/manual.html
options.storage?
(localStorage|sessionStorage)Storage backend. Has to implement the Storage interface of the Web Storage API.
Default:
localStorage
options.disabledPlugins?
(array<string>)Default:
[]
options.connectionCallback?
((jid: string, status: number, condition?: string) => void)Default:
undefined
options.onUserRequestsToGoOnline?
(() => void)If the user requests to go online again, this function is called. Default: The login dialog is shown.
Default:
loginDialog
jsxc.numberOfCachedAccounts: number¶
Number of restored connections.
jsxc.start(boshUrl, jid, sid, rid)¶
With JSXC you can also continue a previous established BOSH session.
Arguments¶
boshUrl
(string)- The URL of your BOSH service.
jid
(string)- Your Jabber Id with or without resource. E.g.
klaus@jsxc.org
orklaus@jsxc.org/desktop
.
sid
(string)- Your Session ID from your pre-bind session.
rid
(string)- Your Request ID from your pre-bind session.
Returns¶
Promise<void>
- Promise is resolved if the connection is established and the UI loaded.
jsxc.start(boshUrl, jid, password)¶
Start a new connection with the given service and credentials.
Arguments¶
boshUrl
(string)- The URL of your BOSH service.
jid
(string)- Your Jabber Id with or without resource. E.g.
klaus@jsxc.org
orklaus@jsxc.org/desktop
.
password
(string)- Corresponding password to your Jabber Id.
Returns¶
Promise<void>
- Promise is resolved if the connection is established and the UI loaded.
jsxc.start()¶
Show an empty contact list which allows the user to connect to a service by itself.
Returns¶
Promise<void>
- Promise is resolved if the UI is loaded.
jsxc.startAndPause(boshUrl, jid, password)¶
Same as jsxc.start
, but just connects to the XMPP and stops afterwards. Can be used to connect before a form is submitted, or similar.
Returns¶
Promise<void>
- Promise is resolved if the connection is established.
jsxc.watchForm(formElement, usernameElement, passwordElement)¶
Watch a login form and use credentials to establish an XMPP connection. You can
provide options with options.loadConnectionOptions
.
Arguments¶
formElement
(JQuery)- Form element which should be watched for a submit event.
usernameElement
(JQuery)- If the form is submitted get the username from this element.
passwordElement
(JQuery)- If the form is submitted get the password from this element.
jsxc.watchLogoutClick(element)¶
Watch a logout element and disconnect JSXC before the original click action is processed.
Arguments¶
element
(JQuery)- Logout element which should be watched for a click event.
Development¶
jsxc.enableDebugMode()¶
Enable debug mode for more log messages.
jsxc.disableDebugMode()¶
Disable debug mode.
Account¶
account.getContact(jid)¶
Arguments¶
jid
(string)- Bare JID of contact.
Returns¶
Contact|MultiUserContact
- Depending on the kind of user, a contact or multi-user contact is returned.
account.createMultiUserContact(jid, nickname, displayName?, password?)¶
Creates a new MUC room.
Arguments¶
jid
(string)- Bare JID of new multi-user contact.
nickname
(string)- Desired nickname in MUC room.
displayName?
(string)- Contact name in roster.
password?
(string)- Protect room with password.
Returns¶
MultiUserContact
- Multi-user contact is returned.
Contact¶
contact.openChatWindow()¶
Opens the chat window.
contact.openChatWindowProminently()¶
Opens the chat window and highlights it.
contact.addToContactList()¶
Adds contact to roster or bookmark storage.
MultiUserContact extends Contact¶
multiUserContact.join()¶
Join the given room.
multiUserContact.leave()¶
Leave the given room.
multiUserContact.destroy()¶
Destroy the given room.
Services¶
JSXC.register(service, domain, callback?)¶
Arguments¶
service
(string)- The URL of your BOSH service.
domain
(string)- Register a new user with this domain.
callback?
((form: Form) => Promise<Form>)- If you like to display a custom form, provide a callback.
Returns¶
Promise<void>
- Promise is resolved if the user was successfully registered.
JSXC.testBOSHServer(url, domain)¶
Allows you test if a BOSH server is reachable and serving the given domain.
Arguments¶
url
(string)- URL which you like to test.
domain
(string)- Domain which you like to test.
Returns¶
Promise<string>
If the BOSH server is reachable the promise resolves with a constant success string.
In the error case the promise is resolved with an error object. You can call
toString()
to get the error message in english orgetErrorCode()
to get a more generic error code. You find a list of all messages and codes insrc/api/v1/testBOSHServer.ts
.
How to’s¶
Screen Sharing¶
Screen sharing is only supported by Chrome and Firefox (before version 52) through a domain-specific extension. This means, that every domain which tries to access the desktop needs to release his own extension. There are example implementations for Firefox and Chrome which are easy to adapt.
Starting from version 52, Firefox doesn’t require an extension for screen sharing.
Screen sharing also requires an encrypted connection (https), otherwise the browser will reject any screen media request.
WebRTC how to¶
Why STUN/TURN?¶
A STUN (Session Traversal Utilities for NAT) server will allow our two end-nodes to know what their public IP is, as we most often sit behind a router in a LAN with private IP addresses. It is only used for that “getting to know each other” phase used to gather all informations about how (if proven possible) establishing our peer-to-peer WebRTC communication.
A TURN (Traversal Using Relay NAT) server is a relay server used when peer-to-peer connection cannot be established. In that case your only option is to use an external server as a relay. Symmetrical NAT, encountered more often in corporate networks, is typically the kind of NAT for which a TURN server will be used as a workaround to establish communication.
Public STUN/TURN Servers¶
- stun.stunprotocol.org
(STUN only) is used by default in JSXC. Is known to be prone to DDoS attacks.
Warning
For Russia and parts of Ukraine, this server resolves to 127.0.0.1 (probably as a result of anti-DDoS actions taken by server maintainers). If you experience problems with WebRTC connectivity in JSXC, first of all check the STUN server availability.
URL:
stun:stun.stunprotocol.org
- Google STUN server
(STUN only)
URL:
stun:stun.l.google.com:19302
- numb.viagenie.ca
(STUN/TURN) is a public STUN/TURN server. Requires registration.
Warning
This server is known not to work with Firefox (fails to collect srflx and relay entries).
URL: turn:numb.viagenie.ca
Private STUN/TURN Server¶
Install and configure coturn¶
Below commands are for Debian, adjust to you distribution’s package manager. We need openssl version 1.0.2 minimum to support DTLS (Datagram TLS). I used the testing repo to install recent versions of both openssl and coturn:
apt install openssl/stretch coturn/stretch
You should get validated checks regarding security protocols supported when restarting coturn:
0: TLS supported
0: DTLS supported
0: DTLS 1.2 supported
0: TURN/STUN ALPN supported
0: Third-party authorization (oAuth) supported
0: GCM (AEAD) supported
0: OpenSSL compile-time version: OpenSSL 1.0.2j 26 Sep 2016 (0x100020af)
Now for the configuration (in /etc/turnserver.conf
), a minimum working conf dims down to:
listening-port=3478
tls-listening-port=5349
alt-listening-port=3479
alt-tls-listening-port=5350
listening-ip=PUB.IP.NUM.1
listening-ip=PUB.IP.NUM.2
relay-ip=PUB.IP.NUM.1
min-port=49152
max-port=65535
verbose
fingerprint
use-auth-secret
static-auth-secret
userdb=/var/lib/turn/turndb
realm=example.com
cert=/etc/ssl/certs/coturn_ca.crt
pkey=/etc/ssl/private/coturn.key
dh-file=/etc/turn/dhparam.pem
no-stdout-log
log-file=/var/log/turn/turn.log
no-sslv3
no-tlsv1
This is set up to enable STUN features as well as TURN features. The TLS key/certs have to be fully functional, as TLS is a requirement and not an option (works perfectly fine with Letsencrypt certificate). You need 2 public IPs for STUN to do its magic.
coturn authentication¶
For TURN, because it handles the whole stream, we want it to only accept relaying authenticated nodes. To do that, you need to create at least a user account and a shared secret. They both will be used for ephemeral credential validation. In your terminal, generate an account and declare your shared secret via turnadmin command:
turnadmin -a --db /var/lib/turn/turndb -u username -r example.com -p XXXXXX
turnadmin --db /var/lib/turn/turndb -r example.com --set-secret=XXXXXXXXXXXX
Note
from what I gathered, the user password is not used for ephemeral credentials, only for long-term credentials, which are not secure.
Configure STUN/TURN server in JSXC¶
Static¶
You can pass your STUN/TURN configuration directly to JSXC as init option with the key RTCPeerConfig.iceServers using the format described in the W3C WebRTC working draft:
RTCPeerConfig: {
/** ICE servers like defined in http://www.w3.org/TR/webrtc/#idl-def-RTCIceServer */
iceServers: [{
urls: ['stun:stun.domain1.org', 'stun:stun.domain2.org']
}, {
urls: 'turn:turn.domain3.org',
username: 'user',
credential: 'pass'
}]
}
Dynamic¶
If you like to generate STUN/TURN parameters on the fly, just pass
RTCPeerConfig.url
as init option to JSXC. The endpoint has to respond
with a JSON encoded representation of RTCPeerConfig:
RTCPeerConfig: {
url: '/getWebRTCConfig.php',
/** If true, jsxc send cookies when requesting RTCPeerConfig from the url above */
withCredentials: false,
}
Resources¶
- WebRTC Troubleshooter
- tests all your WebRTC parameter, like Camera, Network or Connectivity.
- Trickle ICE
- can be used to check general STUN/TURN server availability and functioning.
- NAT-Analyzer
- is a tool to check your NAT type (full cone, symmetric etc.) Requires Java.
File Transfer¶
Methods¶
In general JSXC supports currently data channels (WebRTC) and http upload for file transfer. If http upload is enabled it is the preferred method. If the file is larger as the maximum upload limit, JSXC will fall back to data channels if available.
HTTP Upload¶
To use http upload your server should support CORS. If it doesn’t you have to proxy those request and add the CORS header by yourself as in the example shown.
ejabberd Configuration¶
Ejabberd mod_httpupload:
listen:
...
-
port: 5443
module: ejabberd_http
tls: true
certfile: "/etc/ejabberd/certificate.pem"
request_handlers:
...
"upload": mod_http_upload
...
...
modules:
...
mod_http_upload:
docroot: "/ejabberd/upload"
put_url: "https://@HOST@:5443/upload"
custom_headers:
"Access-Control-Allow-Origin": "*"
"Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT"
"Access-Control-Allow-Headers": "Content-Type"
...
Warning
Ejabberd ignores custom headers if your put url is different from your xmpp domain. See processone/ejabberd#1482.
Prosody configuration¶
Prosody mod_http_upload:
Component "localhost" "http_upload"
http_external_url = "https://EXTERNAL_URL/"
http_upload_file_size_limit = 10485760
Apache configuration:
<VirtualHost *:443>
ServerName EXTERNAL_URL
...
<Location /upload/>
# Allow cross site requests
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Content-Type"
Header always set Access-Control-Allow-Methods "OPTIONS, PUT, GET"
RewriteEngine On
# modify status code of preflight request
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
</Location>
SSLProxyEngine on
# Just for testing
#SSLProxyVerify none
#SSLProxyCheckPeerCN off
#SSLProxyCheckPeerName off
#SSLProxyCheckPeerExpire off
ProxyPass /upload/ https://localhost:5281/upload/
</VirtualHost>
WebRTC data channel¶
See our special WebRTC page.
Using JSXC on Windows with IIS¶
I’m not going to go in full details yet on how to fully setup each point.
I actually have a domain, and SSL certificates that I created using Let’s Encrypt, and I’m using https for my entire setup. So this might make things tricky for you if you are only using http with no actual domain at all, but http://localhost/ should just be fine I think??? lol.
I will assume for the most part you do have some knowledge and experience with IIS, php, MySQL, permissions, configuration files, and etc… You can search online using Google or other for “How to secure IIS”, “How to secure wtv”.
My setup:
OS: Windows Server 2016 Data Center (Can be used with any OS that supports IIS)
WWW Server: IIS 10 (Assumed installed)
- IIS Web Platform Installer v5 so you can install next two easy
- IIS Application Request Routing for reverse proxy
- IIS URL ReWrite for reverse proxy
DNS Server: BIND9
php: v7.2.2
XMPP Server: ejabberd v18.01
DB: MySQL
Step 1¶
Make sure your OS, IIS, php, MySQL, Web Application Platform, Application Request Routing, and URL ReWrite module are installed, configured, and working. If you plan on actually testing this outside of localhost, don’t forget to open your firewall ports on the server, port forwarding in your router, and to actually get a domain instead of making fake internal domains local to the server using BIND9 DNS server, any other DNS server, or even just using the host file.
Install ejabberd XMPP Server on the same machine, just follow the steps in the installer, once it ask you for host name you can put domain.com or wtv domain you plan on using for testing. Run the “Start ejabberd shortcut” created by the installer on the desktop. Your web browser will open and say the ejabberd has started if all went well. Login to the admin page http://localhost:5280/admin/ with the user/pwd you typed in the ejabberd installer. You can use this admin page to create more users but for now we can do testing with your admin@domain.com account created during installation of ejabberd.
Important
Once ejabberd is installed and running, open up your web browser and test “http://localhost:5280/http-bind/” or “http://localhost:5280/bosh/” (they both do the same thing) to confirm they are accessible and working. This is what we are going to create a URL ReWrite rule or aka alias for using reverse proxy”.
Step 2¶
Make a folder called www on any drive outside Inetpub. This will make your life more easy for editing instead of having to be in admin mode all the time, security, and backing up.

Change security permissions to allow the user IIS_IURS Read and Execute permissions, depending on what you are doing some subfolders or files might need write access to.

Step 3¶
Decide now if you want JSXC to be a domain or subdomain. Just to be clean, I name my folders like domain.com for a folder/domain or sub.domain.com for a folder/subdomain aka “C:wwwdomain.com” or “C:wwwsub.domain.com”. I’ll be using domain.com for the example.
Create a folder called domain.com in your www folder and dump the JSXC files in this folder. Configure your JSXC install. I’m only using the internal database for the ejabberd server.
Important
Very important create another folder called bosh or http-bind in your domain.com folder, this will be used to create the reverse proxy to allow JSXC XMPP Client to talk with the ejabberd XMPP Server. It will also store a Web.config file that actually has the settings to do the reverse proxy. So your link would be http://domain.com/bosh/ or http://domain.com/http-bind/” wtv you decided ejabbered works with both links using /bosh/ or /http-bind/ same as JSXC does.** – I would like to thank @skyfox675 for the help on this one and showing his config file sample, because I had never done proxies using IIS before.
By now you should of setup something like roundcube webmail, nextcloud, or owncloud to allow you to use JSXC as a plugin/addon, if not you will have to make your own little html or php app to allow you to even use JSXC. Just follow the JSXC installation section, and pay attention to the “Do you want to integrate JSXC into your own web application”.
Step 4¶
Important
Enabling IIS as a proxy server using ARR.
You have to click on the server itself in the IIS Manager on the left, if you have installed Application Routing and Request you should see Application Routing and Request Cache as an icon on the right, double click the icon.

Now that you have Application Routing and Request Cache open, look to the right you should see “Server Proxy Settings” so single click it.

Don’t worry about all the settings on this page, they can be left to default, all you need to do is enable it and click apply on the right.

Step 5¶
Important
Setting up the Web.config file with rules for URL ReWrite.
You can do this two ways either using IIS Manager, expand your website/domain.com and click on the subfolder bosh or http-bind wtv you decided to name it, and using the GUI to create the reverse proxy url rewrite.

Or just creating a text file using notepad and saving it in your bosh or http-bind folder calling Web and saving it as a config file not a txt file making it be “Web.config”.
I used the GUI to make the server variables needed for this ReWrite to work, and used notepad to actually write the config file provided by @skyfox675 in the provided sample.
You need to create some server variables: 1. HTTP_X_FORWARDED_PROTO 2. HTTP_X_FORWARDED_HOST 3. HTTP_X_FORWARDED_PORT 4. ORIGINAL_HOST21


So now travel to Windows File Explorer to “C:wwwdomain.comhttp-bind” or C:wwwdomain.combosh” and create a web.config file if there is none. You can use notepad these files are just text files in the end. Put this text in your new config file, if there was one already created just add this into it by modifying what IIS generated. I hope you know what config files are and how to use them they end up just being xml being just text lol. Don’t forget to edit the host variable to be your domain, in the example I have it set to domain.com on the inboundrule, and for the outboundrule there is a “/(http-bind)” you could do “/(bosh)” if you wanted, same goes for the localhost:5280 section:
<!-- THANKS TO @skyfox675 for providing a sample -->
<!-- I modified the sample to fit my needs and versions -->
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRuleBOSH" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:5280/http-bind/{R:1}" appendQueryString="true" />
<serverVariables>
<set name="ORIGINAL_HOST21" value="{HTTP_HOST}" />
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
<set name="HTTP_X_FORWARDED_PORT" value="5443" />
<set name="HTTP_X_FORWARDED_HOST" value="domain.com" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRuleBOSH" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" serverVariable="RESPONSE_LOCATION" pattern="^http://[^/]+/(.*)" />
<action type="Rewrite" value="http://{ORIGINAL_HOST21}/{C:1}/{R:1}" />
<conditions>
<add input="{ORIGINAL_HOST21}" pattern=".+" />
<add input="{URL}" pattern="^/(http-bind)" />
</conditions>
</rule>
<preConditions>
<remove name="ResponseIsHtml1" />
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
<add input="{RESPONSE_STATUS}" pattern="3\d\d" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<httpErrors errorMode="DetailedLocalOnly" />
<directoryBrowse enabled="false" />
</system.webServer>
</configuration>
What all this does is convert http://domain.com/http-bind/ from the web server side to http://localhost:5280/http-bind” on the ejabberd xmpp server side on the same machine, could be a different machine if you wanted. This also terminates https if you are using it at the IIS server, but that’s another issues for another time.
So for every single application you use JSXC client in with ejjaberd server, you would tell it your xmpp server is located at http://domain.com/http-bind/ so the local machine and remote machines can find the xmpp server, if you would not do this and only did localhost, the remote machines would never find the xmpp server because locally to themselves there is no server.
Doing this also allows you to not have to create more bindings in IIS for your website aka virtual-host causing other issues. My only bindings on IIS for the site I have JSXC running on is port 80 and 443, and I redirect all to 443.
And you are done and things should be working.
Development¶
Developer notes¶
Get code¶
Please execute the following commands to get a copy of the code:
Core¶
git clone https://github.com/jsxc/jsxc.git
Apps¶
git clone https://github.com/nextcloud/jsxc.nextcloud.git
# and/or
git clone https://github.com/jsxc/jsxc.sogo.git
# and/or
git clone https://github.com/jsxc/jsxc.ilias.git
Install yarn¶
We use yarn as our package manager. Please follow there docs to install it.
Warning
We used npm and grunt in the passed to concatenate, convert, and validate our source files. It’s likely that you still find it at some places.
First install all dependencies with yarn install. To build the project, just run yarn start
in its top-level directory. If you like to start a development server and watch all files for
changes, some project offer you yarn dev.
Now you are ready for development.
Workflow¶
- run
yarn watch
in the project root folder - make your modifications in src/ and scss/
- check your results on example/index.html
git add ...
git commit
(should run our pre-commit hook)git push
Notes¶
Yarn commands¶
A few helpful yarn commands you should know to simplify your life.
start
create a production ready buildwatch
create a development build and rerun on file changesdev
similar towatch
, but it will start a development serverfix
beautifies all files and makes sure the pre-commit hook is satisfied
To run a command, execute yarn COMMAND.
Core Structure¶
TODO
Debugging¶
Open your Javascript console (e.g. ctrl+shift+I) and enter jsxc.storage.setItem(‘debug’, true) to obtain debug messages.
Locales¶
We use webtranslateit.com to organize our translations and wti to synchronise those.
Creating a release¶
- update change log
- update translation
wti pull --all
- update example
- create build
- increase version number in
package.json
- runnode scripts/build-release.js
(use--release
for stable releases)
- increase version number in
- update documentation
- wiki
- website
- publish to app store, npm and similar
- announce new release
- blog post
- mailing list
References¶
External REST specification¶
External REST API of the Nextcloud JSXC app.
Version 1¶
Schema¶
All API access should over HTTPS, and accessed the https://YOUR_CLOUD/index.php/apps/ojsxc/ajax/
.
All data is sent and received as JSON. Every request has to contain a signature to verify the request.
Client Errors¶
- 500 Internal Server Error:
{"result": "error", "data": {"msg":"An error occured"}}
Header Signature¶
Every request to an API endpoint needs a valid X-JSXC-SIGNATURE header of the
form HASH_ALGO=hmac(HASH_ALGO, REQUEST_BODY, API_SECRET)
.
Endpoints¶
Check Password¶
POST /externalApi.php
Name | Type | Description |
---|---|---|
operation | “checkPassword” | |
username | string | |
password | string | |
domain | string | The domain is used to check additionally
the password for username@domain (optional) |
Status: 200 OK
{
"result": "noauth"
}
Status: 200 OK
{
"result": "success",
"data": {
"uid": "foobar"
}
}
Version 2 (draft)¶
Warning
This version is still in development!
Schema¶
All API access should over HTTPS, and accessed the https://YOUR_CLOUD/index.php/apps/ojsxc/api/v2/
. All
data is sent and received as JSON. Every request has to contain a signature to verify the request.
Client Errors¶
- 500 Internal Server Error:
{"result": "error", "data": {"msg":"An error occured"}}
Header Signature¶
Every request to an API endpoint needs a valid X-JSXC-SIGNATURE header of the form HASH_ALGO=hmac(HASH_ALGO, REQUEST_BODY, API_SECRET)
.
Endpoints¶
Check Password¶
POST /checkPassword
Name | Type | Description |
---|---|---|
username | string | |
password | string | |
domain | string | The domain is used to check additionally
the password for username@domain (optional) |
Status: 200 OK
{
"result": "noauth"
}
Status: 200 OK
{
"result": "success",
"data": {
"uid": "foobar"
}
}