diff --git a/.releaseconfig.json b/.releaseconfig.json
index 6f9d0f5..3ce9936 100644
--- a/.releaseconfig.json
+++ b/.releaseconfig.json
@@ -1,3 +1,6 @@
{
- "plugins": ["iobroker", "license"]
+ "plugins": ["iobroker", "license"],
+ "exec": {
+ "before_commit": "npm run build"
+ }
}
diff --git a/README.md b/README.md
index 6d06089..ee4c008 100644
--- a/README.md
+++ b/README.md
@@ -311,17 +311,9 @@ You can set option *Force Web-Sockets* to force using only web-sockets transport
-->
## Changelog
-### 4.0.3 (2022-01-30)
-* (bluefox) Removed the deprecated "passport.socketio" packet
-
-### 4.0.2 (2022-01-30)
-* (bluefox) Removed "force web sockets" option
-
-### 4.0.1 (2022-01-29)
-* (bluefox) Fixed authentication
-
-### 4.0.0 (2022-01-29)
-* (bluefox) Remove socket-io and use only web sockets
+### __WORK IN PROGRESS__
+* (bluefox) Update socket.io library to 2.4.1
+* (bluefox) Used json config for settings
### 3.1.5 (2021-10-22)
* (foxriver76) make error logging on failed authentication more specific
diff --git a/admin/i18n/de/translations.json b/admin/i18n/de/translations.json
new file mode 100644
index 0000000..bacd89d
--- /dev/null
+++ b/admin/i18n/de/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Laufen unter Anwender",
+ "IP": "IP",
+ "Port": "Port",
+ "Secure(HTTPS)": "Verschlüsselung(HTTPS)",
+ "Authentication": "Authentifizierung",
+ "Listen on all IPs": "An allen IP Adressen hören",
+ "help_tip": "Beim Speichern von Einstellungen der Adapter wird sofort neu gestartet.",
+ "Public certificate": "Publikzertifikat",
+ "Private certificate": "Privatzertifikat",
+ "Chained certificate": "Kettenzertifikat",
+ "Let's Encrypt settings": "Einstellungen Let's Encrypt",
+ "Use Lets Encrypt certificates": "Benutzen Let's Encrypt Zertifikate",
+ "Use this instance for automatic update": "Benutze diese Instanz für automatische Updates",
+ "Port to check the domain": "Port um die Domain zu prüfen",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Lesen Sie mehr über Let's Encrypt-Zertifikate",
+ "Undo": "Rückgängig",
+ "Force Web-Sockets": "Web-Sockets erzwingen"
+}
\ No newline at end of file
diff --git a/admin/i18n/en/translations.json b/admin/i18n/en/translations.json
new file mode 100644
index 0000000..22be381
--- /dev/null
+++ b/admin/i18n/en/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Run as",
+ "IP": "IP",
+ "Port": "Port",
+ "Secure(HTTPS)": "Secure(HTTPS)",
+ "Authentication": "Authentication",
+ "Listen on all IPs": "Listen on all IPs",
+ "help_tip": "On save the adapter restarts with new configuration immediately",
+ "Public certificate": "Public certificate",
+ "Private certificate": "Private certificate",
+ "Chained certificate": "Chained certificate",
+ "Let's Encrypt settings": "Let's Encrypt settings",
+ "Use Lets Encrypt certificates": "Use Let's Encrypt certificates",
+ "Use this instance for automatic update": "Use this instance for automatic update",
+ "Port to check the domain": "Port to check the domain",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Read about Let's Encrypt certificates",
+ "Undo": "Undo",
+ "Force Web-Sockets": "Force Web-Sockets"
+}
\ No newline at end of file
diff --git a/admin/i18n/es/translations.json b/admin/i18n/es/translations.json
new file mode 100644
index 0000000..3c438fa
--- /dev/null
+++ b/admin/i18n/es/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Correr como",
+ "IP": "IP",
+ "Port": "Puerto",
+ "Secure(HTTPS)": "Seguro (HTTPS)",
+ "Authentication": "Autenticación",
+ "Listen on all IPs": "Escuchar en todas las direcciones IP",
+ "help_tip": "Al guardar, el adaptador se reinicia con una nueva configuración de inmediato",
+ "Public certificate": "Certificado público",
+ "Private certificate": "Certificado privado",
+ "Chained certificate": "Certificado encadenado",
+ "Let's Encrypt settings": "Vamos a cifrar la configuración",
+ "Use Lets Encrypt certificates": "Utilice los certificados Let's Encrypt",
+ "Use this instance for automatic update": "Use esta instancia para la actualización automática",
+ "Port to check the domain": "Puerto para verificar el dominio",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Lea acerca de los certificados de Let's Encrypt",
+ "Undo": "Deshacer",
+ "Force Web-Sockets": "Forzar Web-Sockets"
+}
\ No newline at end of file
diff --git a/admin/i18n/fr/translations.json b/admin/i18n/fr/translations.json
new file mode 100644
index 0000000..4c4e6c6
--- /dev/null
+++ b/admin/i18n/fr/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Courir comme",
+ "IP": "IP",
+ "Port": "Port",
+ "Secure(HTTPS)": "Sécurisé (HTTPS)",
+ "Authentication": "Authentification",
+ "Listen on all IPs": "Écoutez sur toutes les adresses IP",
+ "help_tip": "Sur enregistrer l'adaptateur redémarre avec la nouvelle configuration immédiatement",
+ "Public certificate": "Certificat public",
+ "Private certificate": "Certificat privé",
+ "Chained certificate": "Certificat chaîné",
+ "Let's Encrypt settings": "Cryptons les paramètres",
+ "Use Lets Encrypt certificates": "Utiliser les certificats Let's Encrypt",
+ "Use this instance for automatic update": "Utilisez cette instance pour la mise à jour automatique",
+ "Port to check the domain": "Port pour vérifier le domaine",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "En savoir plus sur les certificats Let's Encrypt",
+ "Undo": "annuler",
+ "Force Web-Sockets": "Forcer les Web-Sockets"
+}
\ No newline at end of file
diff --git a/admin/i18n/it/translations.json b/admin/i18n/it/translations.json
new file mode 100644
index 0000000..a2ad8dd
--- /dev/null
+++ b/admin/i18n/it/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Correre come",
+ "IP": "IP",
+ "Port": "Porta",
+ "Secure(HTTPS)": "Sicuro (HTTPS)",
+ "Authentication": "Autenticazione",
+ "Listen on all IPs": "Ascolta su tutti gli IP",
+ "help_tip": "Al salvataggio, l'adattatore si riavvia immediatamente con la nuova configurazione",
+ "Public certificate": "Certificato pubblico",
+ "Private certificate": "Certificato privato",
+ "Chained certificate": "Certificato incatenato",
+ "Let's Encrypt settings": "Let's Encrypt settings",
+ "Use Lets Encrypt certificates": "Utilizza Let's Encrypt certificates",
+ "Use this instance for automatic update": "Utilizza questa istanza per l'aggiornamento automatico",
+ "Port to check the domain": "Porta per controllare il dominio",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Leggi i certificati Let's Encrypt",
+ "Undo": "Annullare",
+ "Force Web-Sockets": "Forza Web-Socket"
+}
\ No newline at end of file
diff --git a/admin/i18n/nl/translations.json b/admin/i18n/nl/translations.json
new file mode 100644
index 0000000..73fb978
--- /dev/null
+++ b/admin/i18n/nl/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Rennen als",
+ "IP": "IK P",
+ "Port": "Haven",
+ "Secure(HTTPS)": "Secure (HTTPS)",
+ "Authentication": "authenticatie",
+ "Listen on all IPs": "Luister op alle IP's",
+ "help_tip": "Bij opslaan wordt de adapter onmiddellijk opnieuw opgestart met een nieuwe configuratie",
+ "Public certificate": "Openbaar certificaat",
+ "Private certificate": "Privé certificaat",
+ "Chained certificate": "Geketend certificaat",
+ "Let's Encrypt settings": "Laten we de instellingen versleutelen",
+ "Use Lets Encrypt certificates": "Gebruik Let's Encrypt-certificaten",
+ "Use this instance for automatic update": "Gebruik deze instantie voor automatische update",
+ "Port to check the domain": "Poort om het domein te controleren",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Lees over Let's Encrypt-certificaten",
+ "Undo": "ongedaan maken",
+ "Force Web-Sockets": "Forceer web-sockets"
+}
\ No newline at end of file
diff --git a/admin/i18n/pl/translations.json b/admin/i18n/pl/translations.json
new file mode 100644
index 0000000..59dfda8
--- /dev/null
+++ b/admin/i18n/pl/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Uruchom jako",
+ "IP": "IP",
+ "Port": "Port",
+ "Secure(HTTPS)": "Bezpieczne (HTTPS)",
+ "Authentication": "Uwierzytelnianie",
+ "Listen on all IPs": "Posłuchaj na wszystkich IP",
+ "help_tip": "Po zapisaniu adapter natychmiast uruchamia się ponownie z nową konfiguracją",
+ "Public certificate": "Certyfikat publiczny",
+ "Private certificate": "Prywatny certyfikat",
+ "Chained certificate": "Przykuty certyfikat",
+ "Let's Encrypt settings": "Zakodujmy ustawienia",
+ "Use Lets Encrypt certificates": "Użyj Let's Encrypt certificates",
+ "Use this instance for automatic update": "Użyj tej instancji do automatycznej aktualizacji",
+ "Port to check the domain": "Port do sprawdzenia domeny",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Przeczytaj o certyfikatach Let's Encrypt",
+ "Undo": "Cofnij",
+ "Force Web-Sockets": "Wymuś gniazda sieciowe"
+}
\ No newline at end of file
diff --git a/admin/i18n/pt/translations.json b/admin/i18n/pt/translations.json
new file mode 100644
index 0000000..d16d308
--- /dev/null
+++ b/admin/i18n/pt/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Correr como",
+ "IP": "IP",
+ "Port": "Porta",
+ "Secure(HTTPS)": "Seguro (HTTPS)",
+ "Authentication": "Autenticação",
+ "Listen on all IPs": "Ouça todos os IPs",
+ "help_tip": "Em salvar, o adaptador reinicia com a nova configuração imediatamente",
+ "Public certificate": "Certificado público",
+ "Private certificate": "Certificado privado",
+ "Chained certificate": "Certificado acorrentado",
+ "Let's Encrypt settings": "Vamos criptografar configurações",
+ "Use Lets Encrypt certificates": "Use Vamos criptografar certificados",
+ "Use this instance for automatic update": "Use esta instância para atualização automática",
+ "Port to check the domain": "Porta para verificar o domínio",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Leia sobre os certificados Let's Encrypt",
+ "Undo": "Desfazer",
+ "Force Web-Sockets": "Forçar Web-Sockets"
+}
\ No newline at end of file
diff --git a/admin/i18n/ru/translations.json b/admin/i18n/ru/translations.json
new file mode 100644
index 0000000..fe5181f
--- /dev/null
+++ b/admin/i18n/ru/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "Запустить от пользователя",
+ "IP": "IP",
+ "Port": "Порт",
+ "Secure(HTTPS)": "Шифрование(HTTPS)",
+ "Authentication": "Аутентификация",
+ "Listen on all IPs": "Открыть сокет на всех IP адресах",
+ "help_tip": "Сразу после сохранения настроек драйвер перезапуститься с новыми значениями",
+ "Public certificate": "'Public' сертификат",
+ "Private certificate": "'Private' сертификат",
+ "Chained certificate": "'Chained' сертификат",
+ "Let's Encrypt settings": "Настройки Let's Encrypt",
+ "Use Lets Encrypt certificates": "Использовать сертификаты Let's Encrypt",
+ "Use this instance for automatic update": "Обновлять сертификаты в этом драйвере",
+ "Port to check the domain": "Порт для проверки доменного имени",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "Читать о сертификатах Let's Encrypt",
+ "Undo": "Отменить",
+ "Force Web-Sockets": "Использовать только веб-сокеты"
+}
\ No newline at end of file
diff --git a/admin/i18n/zh-cn/translations.json b/admin/i18n/zh-cn/translations.json
new file mode 100644
index 0000000..27ad2a2
--- /dev/null
+++ b/admin/i18n/zh-cn/translations.json
@@ -0,0 +1,20 @@
+{
+ "Run as": "运行方式",
+ "IP": "知识产权",
+ "Port": "港口",
+ "Secure(HTTPS)": "安全(HTTPS)",
+ "Authentication": "验证",
+ "Listen on all IPs": "监听所有 IP",
+ "help_tip": "保存后适配器立即使用新配置重新启动",
+ "Public certificate": "公共证书",
+ "Private certificate": "私人证书",
+ "Chained certificate": "链式证书",
+ "Let's Encrypt settings": "让我们加密设置",
+ "Use Lets Encrypt certificates": "使用 Let's Encrypt 证书",
+ "Use this instance for automatic update": "使用此实例进行自动更新",
+ "Port to check the domain": "检查域的端口",
+ "Let's Encrypt SSL": "Let's Encrypt SSL",
+ "Read about Let's Encrypt certificates": "阅读 Let's Encrypt 证书",
+ "Undo": "撤消",
+ "Force Web-Sockets": "强制 Web 套接字"
+}
\ No newline at end of file
diff --git a/admin/index.html b/admin/index.html
deleted file mode 100644
index 7a9aee0..0000000
--- a/admin/index.html
+++ /dev/null
@@ -1,159 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 | socket.io adapter settings |
-
-
-
-
-
diff --git a/admin/index_m.html b/admin/index_m.html
deleted file mode 100644
index 54c549d..0000000
--- a/admin/index_m.html
+++ /dev/null
@@ -1,202 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/admin/jsonConfig.json b/admin/jsonConfig.json
new file mode 100644
index 0000000..aef5e2c
--- /dev/null
+++ b/admin/jsonConfig.json
@@ -0,0 +1,160 @@
+{
+ "type": "tabs",
+ "i18n": true,
+ "items": {
+ "mainTab": {
+ "type": "panel",
+ "label": "Main settings",
+ "items": {
+ "bind": {
+ "type": "ip",
+ "listenOnAllPorts": true,
+ "label": "IP",
+ "sm": 12,
+ "md": 8,
+ "lg": 5
+ },
+ "port": {
+ "type": "number",
+ "min": 1,
+ "max": 65565,
+ "label": "Port",
+ "sm": 12,
+ "md": 4,
+ "lg": 3
+ },
+ "secure": {
+ "newLine": true,
+ "type": "checkbox",
+ "label": "Secure(HTTPS)",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ },
+ "certPublic": {
+ "type": "certificate",
+ "hidden": "!data.secure",
+ "certType": "public",
+ "validator": "!data.secure || data.certPublic",
+ "label": "Public certificate",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ },
+ "certPrivate": {
+ "hidden": "!data.secure",
+ "type": "certificate",
+ "certType": "private",
+ "validator": "!data.secure || data.certPrivate",
+ "label": "Private certificate",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ },
+ "certChained": {
+ "hidden": "!data.secure",
+ "type": "certificate",
+ "certType": "chained",
+ "label": "Chained certificate",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ },
+ "auth": {
+ "newLine": true,
+ "type": "checkbox",
+ "confirm": {
+ "condition": "!data.secure && data.auth",
+ "title": "Warning!",
+ "text": "Unsecure_Auth",
+ "ok": "Ignore warning",
+ "cancel": "Disable authentication",
+ "type": "warning",
+ "alsoDependsOn": [
+ "secure"
+ ]
+ },
+ "label": "Authentication",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ },
+ "defaultUser": {
+ "hidden": "!!data.auth",
+ "type": "user",
+ "label": "Run as",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ },
+ "ttl": {
+ "hidden": "!data.auth",
+ "type": "number",
+ "label": "Login timeout",
+ "help": "sec",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ },
+ "forceWebSockets": {
+ "newLine": true,
+ "type": "checkbox",
+ "label": "Force Web-Sockets",
+ "sm": 12,
+ "md": 6,
+ "lg": 2
+ }
+ }
+ },
+ "leTab": {
+ "type": "panel",
+ "label": "Let's Encrypt SSL",
+ "disabled": "!data.secure",
+ "items": {
+ "_image": {
+ "type": "staticImage",
+ "tooltip": "Read about Let's Encrypt certificates",
+ "href": "https://github.com/ioBroker/ioBroker.admin/blob/master/README.md#lets-encrypt-certificates",
+ "src": "../../img/le.png",
+ "style": {
+ "width": 200,
+ "height": 59
+ }
+ },
+ "_link": {
+ "newLine": true,
+ "type": "staticLink",
+ "href": "https://github.com/ioBroker/ioBroker.admin/blob/master/README.md#lets-encrypt-certificates",
+ "label": "Read about Let's Encrypt certificates",
+ "style": {
+ "fontSize": 16,
+ "marginBottom": 20
+ }
+ },
+ "leEnabled": {
+ "newLine": true,
+ "type": "checkbox",
+ "label": "Use Lets Encrypt certificates"
+ },
+ "leUpdate": {
+ "newLine": true,
+ "type": "checkbox",
+ "hidden": "!data.leEnabled",
+ "label": "Use this instance for automatic update"
+ },
+ "lePort": {
+ "newLine": true,
+ "sm": 11,
+ "lg": 4,
+ "type": "number",
+ "hidden": "!data.leEnabled || !data.leUpdate",
+ "label": "Port to check the domain",
+ "style": {
+ "marginTop": 15,
+ "maxWidth": 200
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/admin/words.js b/admin/words.js
deleted file mode 100644
index 9fe5f7b..0000000
--- a/admin/words.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// DO NOT EDIT THIS FILE!!! IT WILL BE AUTOMATICALLY GENERATED FROM src/i18n
-/*global systemDictionary:true */
-'use strict';
-
-systemDictionary = {
- "socket.io adapter settings": { "en": "socket.io adapter settings", "de": "socket.io adapter settings", "ru": "socket.io adapter settings", "pt": "Configurações do adaptador socket.io", "nl": "socket.io-adapterinstellingen", "fr": "Paramètres de l'adaptateur socket.io", "it": "impostazioni della scheda socket.io", "es": "Configuración del adaptador socket.io", "pl": "ustawienia adaptera socket.io"},
- "Run as:": { "en": "Run as", "de": "Laufen unter Anwender", "ru": "Запустить от пользователя", "pt": "Correr como", "nl": "Rennen als", "fr": "Courir comme", "it": "Correre come", "es": "Correr como", "pl": "Uruchom jako"},
- "IP:": { "en": "IP", "de": "IP", "ru": "IP", "pt": "IP", "nl": "IK P", "fr": "IP", "it": "IP", "es": "IP", "pl": "IP"},
- "Port:": { "en": "Port", "de": "Port", "ru": "Порт", "pt": "Porta", "nl": "Haven", "fr": "Port", "it": "Porta", "es": "Puerto", "pl": "Port"},
- "Secure(HTTPS):": { "en": "Secure(HTTPS)", "de": "Verschlüsselung(HTTPS)", "ru": "Шифрование(HTTPS)", "pt": "Seguro (HTTPS)", "nl": "Secure (HTTPS)", "fr": "Sécurisé (HTTPS)", "it": "Sicuro (HTTPS)", "es": "Seguro (HTTPS)", "pl": "Bezpieczne (HTTPS)"},
- "Authentication:": { "en": "Authentication", "de": "Authentifikation", "ru": "Аутентификация", "pt": "Autenticação", "nl": "authenticatie", "fr": "Authentification", "it": "Autenticazione", "es": "Autenticación", "pl": "Poświadczenie"},
- "Listen on all IPs": { "en": "Listen on all IPs", "de": "An allen IP Adressen hören", "ru": "Открыть сокет на всех IP адресах", "pt": "Ouça todos os IPs", "nl": "Luister op alle IP's", "fr": "Écoutez sur toutes les adresses IP", "it": "Ascolta su tutti gli IP", "es": "Escuchar en todas las direcciones IP", "pl": "Posłuchaj na wszystkich IP"},
- "help_tip": { "en": "On save the adapter restarts with new configuration immediately", "de": "Beim Speichern von Einstellungen der Adapter wird sofort neu gestartet.", "ru": "Сразу после сохранения настроек драйвер перезапуститься с новыми значениями", "pt": "Em salvar, o adaptador reinicia com a nova configuração imediatamente", "nl": "Bij opslaan wordt de adapter onmiddellijk opnieuw opgestart met een nieuwe configuratie", "fr": "Sur enregistrer l'adaptateur redémarre avec la nouvelle configuration immédiatement", "it": "Al salvataggio, l'adattatore si riavvia immediatamente con la nuova configurazione", "es": "Al guardar, el adaptador se reinicia con una nueva configuración de inmediato", "pl": "Po zapisaniu adapter natychmiast uruchamia się ponownie z nową konfiguracją"},
- "Public certificate:": { "en": "Public certificate", "de": "Publikzertifikat", "ru": "'Public' сертификат", "pt": "Certificado público", "nl": "Openbaar certificaat", "fr": "Certificat public", "it": "Certificato pubblico", "es": "Certificado público", "pl": "Certyfikat publiczny"},
- "Private certificate:": { "en": "Private certificate", "de": "Privatzertifikat", "ru": "'Private' сертификат", "pt": "Certificado privado", "nl": "Privé certificaat", "fr": "Certificat privé", "it": "Certificato privato", "es": "Certificado privado", "pl": "Prywatny certyfikat"},
- "Chained certificate:": { "en": "Chained certificate", "de": "Kettenzertifikat", "ru": "'Chained' сертификат", "pt": "Certificado acorrentado", "nl": "Geketend certificaat", "fr": "Certificat chaîné", "it": "Certificato incatenato", "es": "Certificado encadenado", "pl": "Przykuty certyfikat"},
- "Force Web-Sockets:": { "en": "Force Web-Sockets", "de": "Nur Web-Sockets", "ru": "Только Web-Sockets", "pt": "Forçar Web-Sockets", "nl": "Force Web-Sockets", "fr": "Forcer les Web-Sockets", "it": "Force Web-Sockets", "es": "Force Web-Sockets", "pl": "Wymuszaj gniazda internetowe"},
- "Let's Encrypt settings": { "en": "Let's Encrypt settings", "de": "Einstellungen Let's Encrypt", "ru": "Настройки Let's Encrypt", "pt": "Vamos criptografar configurações", "nl": "Laten we de instellingen versleutelen", "fr": "Cryptons les paramètres", "it": "Let's Encrypt settings", "es": "Vamos a cifrar la configuración", "pl": "Zakodujmy ustawienia"},
- "Use Lets Encrypt certificates:": { "en": "Use Let's Encrypt certificates", "de": "Benutzen Let's Encrypt Zertifikate", "ru": "Использовать сертификаты Let's Encrypt", "pt": "Use Vamos criptografar certificados", "nl": "Gebruik Let's Encrypt-certificaten", "fr": "Utiliser les certificats Let's Encrypt", "it": "Utilizza Let's Encrypt certificates", "es": "Utilice los certificados Let's Encrypt", "pl": "Użyj Let's Encrypt certificates"},
- "Use this instance for automatic update:": { "en": "Use this instance for automatic update", "de": "Benutze diese Instanz für automatische Updates", "ru": "Обновлять сертификаты в этом драйвере", "pt": "Use esta instância para atualização automática", "nl": "Gebruik deze instantie voor automatische update", "fr": "Utilisez cette instance pour la mise à jour automatique", "it": "Utilizza questa istanza per l'aggiornamento automatico", "es": "Use esta instancia para la actualización automática", "pl": "Użyj tej instancji do automatycznej aktualizacji"},
- "Port to check the domain:": { "en": "Port to check the domain", "de": "Port um die Domain zu prüfen", "ru": "Порт для проверки доменного имени", "pt": "Porta para verificar o domínio", "nl": "Poort om het domein te controleren", "fr": "Port pour vérifier le domaine", "it": "Porta per controllare il dominio", "es": "Puerto para verificar el dominio", "pl": "Port do sprawdzenia domeny"}
-};
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 2d4ea23..264c457 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -143,7 +143,9 @@ function words2languages(src) {
fs.mkdirSync(src + 'i18n/');
}
for (const l in langs) {
- if (!langs.hasOwnProperty(l)) continue;
+ if (!langs.hasOwnProperty(l)) {
+ continue;
+ }
const keys = Object.keys(langs[l]);
//keys.sort();
const obj = {};
@@ -182,7 +184,9 @@ function words2languagesFlat(src) {
const keys = Object.keys(langs.en);
//keys.sort();
for (const l in langs) {
- if (!langs.hasOwnProperty(l)) continue;
+ if (!langs.hasOwnProperty(l)) {
+ continue;
+ }
const obj = {};
for (let k = 0; k < keys.length; k++) {
obj[keys[k]] = langs[l][keys[k]];
@@ -398,4 +402,16 @@ gulp.task('updateReadme', done => {
done();
});
-gulp.task('default', gulp.series('updatePackages', 'updateReadme'));
\ No newline at end of file
+gulp.task('copySocketIo', done => {
+ let socket = require.resolve('socket.io-client').replace(/\\/g, '/');
+ // node_modules/socket.io-client/build/cjs/index.js
+ const parts = socket.split('/');
+ parts.pop();
+ parts.pop();
+ parts.push('dist');
+ parts.push('socket.io.js');
+ fs.writeFileSync(__dirname + '/lib/socket.io.js', fs.readFileSync(parts.join('/')));
+ done();
+});
+
+gulp.task('default', gulp.series('copySocketIo'));
\ No newline at end of file
diff --git a/io-package.json b/io-package.json
index c8dd9d9..f918d2f 100644
--- a/io-package.json
+++ b/io-package.json
@@ -122,14 +122,21 @@
"extIcon": "https://raw.githubusercontent.com/ioBroker/ioBroker.socketio/master/admin/socketio.png",
"type": "communication",
"stopBeforeUpdate": true,
- "materialize": true,
"compact": true,
"stopTimeout": 5000,
+ "adminUI": {
+ "config": "json"
+ },
"dependencies": [
{
"js-controller": ">=2.0.0"
}
],
+ "globalDependencies": [
+ {
+ "admin": ">=5.0.0"
+ }
+ ],
"restartAdapters": [
"web"
],
@@ -149,6 +156,7 @@
"certPrivate": "",
"certChained": "",
"defaultUser": "admin",
+ "forceWebSockets": false,
"leEnabled": false,
"leUpdate": false,
"leCheckPort": 80
diff --git a/lib/passportSocket.js b/lib/passportSocket.js
deleted file mode 100644
index c2ae47c..0000000
--- a/lib/passportSocket.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// Originally taken from here: https://github.com/jfromaniello/passport.socketio/blob/master/lib/index.js
-// Copyright Licensed under the MIT-License. 2012-2013 José F. Romaniello.
-
-function parseCookie(auth, cookieHeader) {
- const cookieParser = auth.cookieParser(auth.secret);
- const req = {
- headers: {
- cookie: cookieHeader
- }
- };
-
- let result;
-
- cookieParser(req, {}, err => {
- if (err) {
- throw err;
- }
- result = req.signedCookies || req.cookies;
- });
-
- return result;
-}
-
-function authorize(options) {
- const defaults = {
- key: 'connect.sid',
- secret: null,
- store: null,
- userProperty: 'user'
- };
-
- const auth = Object.assign({}, defaults, options);
-
- if (!auth.passport) {
- throw new Error('passport is required to use require(\'passport\'), please install passport');
- }
-
- if (!auth.cookieParser) {
- throw new Error('cookieParser is required use require(\'cookie-parser\'), connect.cookieParser or express.cookieParser');
- }
-
- return function (data, accept) {
- data.cookie = parseCookie(auth, data.headers.cookie || '');
- data.sessionID = data.cookie[auth.key] || '';
- data[auth.userProperty] = {
- logged_in: false
- };
-
- auth.store.get(data.sessionID, (err, session) => {
- if (err) {
- return auth.fail(data, 'Error in session store:\n' + err.message, true, accept);
- } else
- if (!session) {
- return auth.fail(data, 'No session found', false, accept);
- } else
- if (!session[auth.passport._key]) {
- return auth.fail(data, 'Passport was not initialized', true, accept);
- }
-
- const userKey = session[auth.passport._key].user;
-
- if (typeof userKey === 'undefined') {
- return auth.fail(data, 'User not authorized through passport. (User Property not found)', false, accept);
- }
-
- auth.passport.deserializeUser(userKey, data, (err, user) => {
- if (err) {
- return auth.fail(data, err, true, accept);
- } else
- if (!user) {
- return auth.fail(data, 'User not found', false, accept);
- }
- data[auth.userProperty] = user;
- data[auth.userProperty].logged_in = true;
- auth.success(data, accept);
- });
- });
- };
-}
-
-exports.authorize = authorize;
\ No newline at end of file
diff --git a/lib/socket.io.js b/lib/socket.io.js
new file mode 100644
index 0000000..50e33f6
--- /dev/null
+++ b/lib/socket.io.js
@@ -0,0 +1,9 @@
+/*!
+ * Socket.IO v2.4.0
+ * (c) 2014-2021 Guillermo Rauch
+ * Released under the MIT License.
+ */
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.io=e():t.io=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){function r(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var n,r=o(t),i=r.source,p=r.id,u=r.path,h=c[p]&&u in c[p].nsps,f=e.forceNew||e["force new connection"]||!1===e.multiplex||h;return f?(a("ignoring socket cache for %s",i),n=s(i,e)):(c[p]||(a("new io instance for %s",i),c[p]=s(i,e)),n=c[p]),r.query&&!e.query&&(e.query=r.query),n.socket(r.path,e)}var o=n(1),i=n(7),s=n(12),a=n(3)("socket.io-client");t.exports=e=r;var c=e.managers={};e.protocol=i.protocol,e.connect=r,e.Manager=n(12),e.Socket=n(37)},function(t,e,n){function r(t,e){var n=t;e=e||"undefined"!=typeof location&&location,null==t&&(t=e.protocol+"//"+e.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?e.protocol+t:e.host+t),/^(https?|wss?):\/\//.test(t)||(i("protocol-less url %s",t),t="undefined"!=typeof e?e.protocol+"//"+t:"https://"+t),i("parse %s",t),n=o(t)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";var r=n.host.indexOf(":")!==-1,s=r?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+s+":"+n.port,n.href=n.protocol+"://"+s+(e&&e.port===n.port?"":":"+n.port),n}var o=n(2),i=n(3)("socket.io-client:url");t.exports=r},function(t,e){function n(t,e){var n=/\/{2,9}/g,r=e.replace(n,"/").split("/");return"/"!=e.substr(0,1)&&0!==e.length||r.splice(0,1),"/"==e.substr(e.length-1,1)&&r.splice(r.length-1,1),r}function r(t,e){var n={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(t,e,r){e&&(n[e]=r)}),n}var o=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,i=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];t.exports=function(t){var e=t,s=t.indexOf("["),a=t.indexOf("]");s!=-1&&a!=-1&&(t=t.substring(0,s)+t.substring(s,a).replace(/:/g,";")+t.substring(a,t.length));for(var c=o.exec(t||""),p={},u=14;u--;)p[i[u]]=c[u]||"";return s!=-1&&a!=-1&&(p.source=e,p.host=p.host.substring(1,p.host.length-1).replace(/;/g,":"),p.authority=p.authority.replace("[","").replace("]","").replace(/;/g,":"),p.ipv6uri=!0),p.pathNames=n(p,p.path),p.queryKey=r(p,p.query),p}},function(t,e,n){(function(r){"use strict";function o(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+t[0]+(n?"%c ":" ")+"+"+e.humanize(this.diff),n){var r="color: "+this.color;t.splice(1,0,r,"color: inherit");var o=0,i=0;t[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(o++,"%c"===t&&(i=o))}),t.splice(i,0,r)}}function s(){return"object"===("undefined"==typeof console?"undefined":u(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=t}catch(n){}}function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"!=typeof r&&"env"in r&&(t=r.env.DEBUG),t}function p(){try{return window.localStorage}catch(t){}}var u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};e=t.exports=n(5),e.log=s,e.formatArgs=i,e.save=a,e.load=c,e.useColors=o,e.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:p(),e.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],e.formatters.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},e.enable(c())}).call(e,n(4))},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(t){if(u===setTimeout)return setTimeout(t,0);if((u===n||!u)&&setTimeout)return u=setTimeout,setTimeout(t,0);try{return u(t,0)}catch(e){try{return u.call(null,t,0)}catch(e){return u.call(this,t,0)}}}function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(t);try{return h(t)}catch(e){try{return h.call(null,t)}catch(e){return h.call(this,t)}}}function s(){y&&l&&(y=!1,l.length?d=l.concat(d):g=-1,d.length&&a())}function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];++g1)for(var n=1;n100)){var e=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(t);if(e){var n=parseFloat(e[1]),r=(e[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*u;case"days":case"day":case"d":return n*p;case"hours":case"hour":case"hrs":case"hr":case"h":return n*c;case"minutes":case"minute":case"mins":case"min":case"m":return n*a;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function r(t){return t>=p?Math.round(t/p)+"d":t>=c?Math.round(t/c)+"h":t>=a?Math.round(t/a)+"m":t>=s?Math.round(t/s)+"s":t+"ms"}function o(t){return i(t,p,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s,"second")||t+" ms"}function i(t,e,n){if(!(t0)return n(t);if("number"===i&&isNaN(t)===!1)return e["long"]?o(t):r(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))}},function(t,e,n){function r(){}function o(t){var n=""+t.type;if(e.BINARY_EVENT!==t.type&&e.BINARY_ACK!==t.type||(n+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(n+=t.nsp+","),null!=t.id&&(n+=t.id),null!=t.data){var r=i(t.data);if(r===!1)return m;n+=r}return f("encoded %j as %s",t,n),n}function i(t){try{return JSON.stringify(t)}catch(e){return!1}}function s(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet),i=n.buffers;i.unshift(r),e(i)}d.removeBlobs(t,n)}function a(){this.reconstructor=null}function c(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.type])return h("unknown packet type "+r.type);if(e.BINARY_EVENT===r.type||e.BINARY_ACK===r.type){for(var o="";"-"!==t.charAt(++n)&&(o+=t.charAt(n),n!=t.length););if(o!=Number(o)||"-"!==t.charAt(n))throw new Error("Illegal attachments");r.attachments=Number(o)}if("/"===t.charAt(n+1))for(r.nsp="";++n;){var i=t.charAt(n);if(","===i)break;if(r.nsp+=i,n===t.length)break}else r.nsp="/";var s=t.charAt(n+1);if(""!==s&&Number(s)==s){for(r.id="";++n;){var i=t.charAt(n);if(null==i||Number(i)!=i){--n;break}if(r.id+=t.charAt(n),n===t.length)break}r.id=Number(r.id)}if(t.charAt(++n)){var a=p(t.substr(n)),c=a!==!1&&(r.type===e.ERROR||y(a));if(!c)return h("invalid payload");r.data=a}return f("decoded %s as %j",t,r),r}function p(t){try{return JSON.parse(t)}catch(e){return!1}}function u(t){this.reconPack=t,this.buffers=[]}function h(t){return{type:e.ERROR,data:"parser error: "+t}}var f=n(3)("socket.io-parser"),l=n(8),d=n(9),y=n(10),g=n(11);e.protocol=4,e.types=["CONNECT","DISCONNECT","EVENT","ACK","ERROR","BINARY_EVENT","BINARY_ACK"],e.CONNECT=0,e.DISCONNECT=1,e.EVENT=2,e.ACK=3,e.ERROR=4,e.BINARY_EVENT=5,e.BINARY_ACK=6,e.Encoder=r,e.Decoder=a;var m=e.ERROR+'"encode error"';r.prototype.encode=function(t,n){if(f("encoding packet %j",t),e.BINARY_EVENT===t.type||e.BINARY_ACK===t.type)s(t,n);else{var r=o(t);n([r])}},l(a.prototype),a.prototype.add=function(t){var n;if("string"==typeof t)n=c(t),e.BINARY_EVENT===n.type||e.BINARY_ACK===n.type?(this.reconstructor=new u(n),0===this.reconstructor.reconPack.attachments&&this.emit("decoded",n)):this.emit("decoded",n);else{if(!g(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");n=this.reconstructor.takeBinaryData(t),n&&(this.reconstructor=null,this.emit("decoded",n))}},a.prototype.destroy=function(){this.reconstructor&&this.reconstructor.finishedReconstruction()},u.prototype.takeBinaryData=function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=d.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null},u.prototype.finishedReconstruction=function(){this.reconPack=null,this.buffers=[]}},function(t,e,n){function r(t){if(t)return o(t)}function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}t.exports=r,r.prototype.on=r.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},r.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var r,o=0;o0&&!this.encoding){var t=this.packetBuffer.shift();this.packet(t)}},r.prototype.cleanup=function(){u("cleanup");for(var t=this.subs.length,e=0;e=this._reconnectionAttempts)u("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var e=this.backoff.duration();u("will wait %dms before reconnect attempt",e),this.reconnecting=!0;var n=setTimeout(function(){t.skipReconnect||(u("attempting reconnect"),t.emitAll("reconnect_attempt",t.backoff.attempts),t.emitAll("reconnecting",t.backoff.attempts),t.skipReconnect||t.open(function(e){e?(u("reconnect attempt error"),t.reconnecting=!1,t.reconnect(),t.emitAll("reconnect_error",e.data)):(u("reconnect success"),t.onreconnect())}))},e);this.subs.push({destroy:function(){clearTimeout(n)}})}},r.prototype.onreconnect=function(){var t=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",t)}},function(t,e,n){t.exports=n(14),t.exports.parser=n(22)},function(t,e,n){function r(t,e){return this instanceof r?(e=e||{},t&&"object"==typeof t&&(e=t,t=null),t?(t=u(t),e.hostname=t.host,e.secure="https"===t.protocol||"wss"===t.protocol,e.port=t.port,t.query&&(e.query=t.query)):e.host&&(e.hostname=u(e.host).host),this.secure=null!=e.secure?e.secure:"undefined"!=typeof location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.agent=e.agent||!1,this.hostname=e.hostname||("undefined"!=typeof location?location.hostname:"localhost"),this.port=e.port||("undefined"!=typeof location&&location.port?location.port:this.secure?443:80),this.query=e.query||{},"string"==typeof this.query&&(this.query=h.decode(this.query)),this.upgrade=!1!==e.upgrade,this.path=(e.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!e.forceJSONP,this.jsonp=!1!==e.jsonp,this.forceBase64=!!e.forceBase64,this.enablesXDR=!!e.enablesXDR,this.withCredentials=!1!==e.withCredentials,this.timestampParam=e.timestampParam||"t",this.timestampRequests=e.timestampRequests,this.transports=e.transports||["polling","websocket"],this.transportOptions=e.transportOptions||{},this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.policyPort=e.policyPort||843,this.rememberUpgrade=e.rememberUpgrade||!1,this.binaryType=null,this.onlyBinaryUpgrades=e.onlyBinaryUpgrades,this.perMessageDeflate=!1!==e.perMessageDeflate&&(e.perMessageDeflate||{}),!0===this.perMessageDeflate&&(this.perMessageDeflate={}),this.perMessageDeflate&&null==this.perMessageDeflate.threshold&&(this.perMessageDeflate.threshold=1024),this.pfx=e.pfx||null,this.key=e.key||null,this.passphrase=e.passphrase||null,this.cert=e.cert||null,this.ca=e.ca||null,this.ciphers=e.ciphers||null,this.rejectUnauthorized=void 0===e.rejectUnauthorized||e.rejectUnauthorized,this.forceNode=!!e.forceNode,this.isReactNative="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),("undefined"==typeof self||this.isReactNative)&&(e.extraHeaders&&Object.keys(e.extraHeaders).length>0&&(this.extraHeaders=e.extraHeaders),e.localAddress&&(this.localAddress=e.localAddress)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingIntervalTimer=null,this.pingTimeoutTimer=null,void this.open()):new r(t,e)}function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}var i=n(15),s=n(8),a=n(3)("engine.io-client:socket"),c=n(36),p=n(22),u=n(2),h=n(30);t.exports=r,r.priorWebsocketSuccess=!1,s(r.prototype),r.protocol=p.protocol,r.Socket=r,r.Transport=n(21),r.transports=n(15),r.parser=n(22),r.prototype.createTransport=function(t){a('creating transport "%s"',t);var e=o(this.query);e.EIO=p.protocol,e.transport=t;var n=this.transportOptions[t]||{};this.id&&(e.sid=this.id);var r=new i[t]({query:e,socket:this,agent:n.agent||this.agent,hostname:n.hostname||this.hostname,port:n.port||this.port,secure:n.secure||this.secure,path:n.path||this.path,forceJSONP:n.forceJSONP||this.forceJSONP,jsonp:n.jsonp||this.jsonp,forceBase64:n.forceBase64||this.forceBase64,enablesXDR:n.enablesXDR||this.enablesXDR,withCredentials:n.withCredentials||this.withCredentials,timestampRequests:n.timestampRequests||this.timestampRequests,timestampParam:n.timestampParam||this.timestampParam,policyPort:n.policyPort||this.policyPort,pfx:n.pfx||this.pfx,key:n.key||this.key,passphrase:n.passphrase||this.passphrase,cert:n.cert||this.cert,ca:n.ca||this.ca,ciphers:n.ciphers||this.ciphers,rejectUnauthorized:n.rejectUnauthorized||this.rejectUnauthorized,perMessageDeflate:n.perMessageDeflate||this.perMessageDeflate,extraHeaders:n.extraHeaders||this.extraHeaders,forceNode:n.forceNode||this.forceNode,localAddress:n.localAddress||this.localAddress,requestTimeout:n.requestTimeout||this.requestTimeout,protocols:n.protocols||void 0,isReactNative:this.isReactNative});return r},r.prototype.open=function(){var t;if(this.rememberUpgrade&&r.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1)t="websocket";else{if(0===this.transports.length){var e=this;return void setTimeout(function(){e.emit("error","No transports available")},0)}t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(n){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)},r.prototype.setTransport=function(t){a("setting transport %s",t.name);var e=this;this.transport&&(a("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=t,t.on("drain",function(){e.onDrain()}).on("packet",function(t){e.onPacket(t)}).on("error",function(t){e.onError(t)}).on("close",function(){e.onClose("transport close")})},r.prototype.probe=function(t){function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.transport.supportsBinary;h=h||e}h||(a('probe transport "%s" opened',t),u.send([{type:"ping",data:"probe"}]),u.once("packet",function(e){if(!h)if("pong"===e.type&&"probe"===e.data){if(a('probe transport "%s" pong',t),f.upgrading=!0,f.emit("upgrading",u),!u)return;r.priorWebsocketSuccess="websocket"===u.name,a('pausing current transport "%s"',f.transport.name),f.transport.pause(function(){h||"closed"!==f.readyState&&(a("changing transport and sending upgrade packet"),p(),f.setTransport(u),u.send([{type:"upgrade"}]),f.emit("upgrade",u),u=null,f.upgrading=!1,f.flush())})}else{a('probe transport "%s" failed',t);var n=new Error("probe error");n.transport=u.name,f.emit("upgradeError",n)}}))}function n(){h||(h=!0,p(),u.close(),u=null)}function o(e){var r=new Error("probe error: "+e);r.transport=u.name,n(),a('probe transport "%s" failed because of error: %s',t,e),f.emit("upgradeError",r)}function i(){o("transport closed")}function s(){o("socket closed")}function c(t){u&&t.name!==u.name&&(a('"%s" works - aborting "%s"',t.name,u.name),n())}function p(){u.removeListener("open",e),u.removeListener("error",o),u.removeListener("close",i),f.removeListener("close",s),f.removeListener("upgrading",c)}a('probing transport "%s"',t);var u=this.createTransport(t,{probe:1}),h=!1,f=this;r.priorWebsocketSuccess=!1,u.once("open",e),u.once("error",o),u.once("close",i),this.once("close",s),this.once("upgrading",c),u.open()},r.prototype.onOpen=function(){if(a("socket open"),this.readyState="open",r.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.upgrade&&this.transport.pause){a("starting upgrade probes");for(var t=0,e=this.upgrades.length;t1?{type:b[o],data:t.substring(1)}:{type:b[o]}:w}var i=new Uint8Array(t),o=i[0],s=f(t,1);return k&&"blob"===n&&(s=new k([s])),{type:b[o],data:s}},e.decodeBase64Packet=function(t,e){var n=b[t.charAt(0)];if(!p)return{type:n,data:{base64:!0,data:t.substr(1)}};var r=p.decode(t.substr(1));return"blob"===e&&k&&(r=new k([r])),{type:n,data:r}},e.encodePayload=function(t,n,r){function o(t){return t.length+":"+t}function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}"function"==typeof n&&(r=n,n=null);var s=h(t);return n&&s?k&&!m?e.encodePayloadAsBlob(t,r):e.encodePayloadAsArrayBuffer(t,r):t.length?void c(t,i,function(t,e){return r(e.join(""))}):r("0:")},e.decodePayload=function(t,n,r){if("string"!=typeof t)return e.decodePayloadAsBinary(t,n,r);"function"==typeof n&&(r=n,n=null);var o;if(""===t)return r(w,0,1);for(var i,s,a="",c=0,p=t.length;c0;){for(var s=new Uint8Array(o),a=0===s[0],c="",p=1;255!==s[p];p++){if(c.length>310)return r(w,0,1);c+=s[p]}o=f(o,2+c.length),c=parseInt(c);var u=f(o,0,c);if(a)try{u=String.fromCharCode.apply(null,new Uint8Array(u))}catch(h){var l=new Uint8Array(u);u="";for(var p=0;pr&&(n=r),e>=r||e>=n||0===r)return new ArrayBuffer(0);for(var o=new Uint8Array(t),i=new Uint8Array(n-e),s=e,a=0;s=55296&&e<=56319&&o65535&&(e-=65536,o+=d(e>>>10&1023|55296),e=56320|1023&e),o+=d(e);return o}function o(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate U+"+t.toString(16).toUpperCase()+" is not a scalar value");return!1}return!0}function i(t,e){return d(t>>e&63|128)}function s(t,e){if(0==(4294967168&t))return d(t);var n="";return 0==(4294965248&t)?n=d(t>>6&31|192):0==(4294901760&t)?(o(t,e)||(t=65533),n=d(t>>12&15|224),n+=i(t,6)):0==(4292870144&t)&&(n=d(t>>18&7|240),n+=i(t,12),n+=i(t,6)),n+=d(63&t|128)}function a(t,e){e=e||{};for(var r,o=!1!==e.strict,i=n(t),a=i.length,c=-1,p="";++c=f)throw Error("Invalid byte index");var t=255&h[l];if(l++,128==(192&t))return 63&t;throw Error("Invalid continuation byte")}function p(t){var e,n,r,i,s;if(l>f)throw Error("Invalid byte index");if(l==f)return!1;if(e=255&h[l],l++,0==(128&e))return e;if(192==(224&e)){if(n=c(),s=(31&e)<<6|n,s>=128)return s;throw Error("Invalid continuation byte")}if(224==(240&e)){if(n=c(),r=c(),s=(15&e)<<12|n<<6|r,s>=2048)return o(s,t)?s:65533;throw Error("Invalid continuation byte")}if(240==(248&e)&&(n=c(),r=c(),i=c(),s=(7&e)<<18|n<<12|r<<6|i,s>=65536&&s<=1114111))return s;throw Error("Invalid UTF-8 detected")}function u(t,e){e=e||{};var o=!1!==e.strict;h=n(t),f=h.length,l=0;for(var i,s=[];(i=p(o))!==!1;)s.push(i);return r(s)}/*! https://mths.be/utf8js v2.1.2 by @mathias */
+var h,f,l,d=String.fromCharCode;t.exports={version:"2.1.2",encode:a,decode:u}},function(t,e){!function(t){"use strict";e.encode=function(e){var n,r=new Uint8Array(e),o=r.length,i="";for(n=0;n>2],i+=t[(3&r[n])<<4|r[n+1]>>4],i+=t[(15&r[n+1])<<2|r[n+2]>>6],i+=t[63&r[n+2]];return o%3===2?i=i.substring(0,i.length-1)+"=":o%3===1&&(i=i.substring(0,i.length-2)+"=="),i},e.decode=function(e){var n,r,o,i,s,a=.75*e.length,c=e.length,p=0;"="===e[e.length-1]&&(a--,"="===e[e.length-2]&&a--);var u=new ArrayBuffer(a),h=new Uint8Array(u);for(n=0;n>4,h[p++]=(15&o)<<4|i>>2,h[p++]=(3&i)<<6|63&s;return u}}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")},function(t,e){function n(t){return t.map(function(t){if(t.buffer instanceof ArrayBuffer){var e=t.buffer;if(t.byteLength!==e.byteLength){var n=new Uint8Array(t.byteLength);n.set(new Uint8Array(e,t.byteOffset,t.byteLength)),e=n.buffer}return e}return t})}function r(t,e){e=e||{};var r=new i;return n(t).forEach(function(t){r.append(t)}),e.type?r.getBlob(e.type):r.getBlob()}function o(t,e){return new Blob(n(t),e||{})}var i="undefined"!=typeof i?i:"undefined"!=typeof WebKitBlobBuilder?WebKitBlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder&&MozBlobBuilder,s=function(){try{var t=new Blob(["hi"]);return 2===t.size}catch(e){return!1}}(),a=s&&function(){try{var t=new Blob([new Uint8Array([1,2])]);return 2===t.size}catch(e){return!1}}(),c=i&&i.prototype.append&&i.prototype.getBlob;"undefined"!=typeof Blob&&(r.prototype=Blob.prototype,o.prototype=Blob.prototype),t.exports=function(){return s?a?Blob:o:c?r:void 0}()},function(t,e){e.encode=function(t){var e="";for(var n in t)t.hasOwnProperty(n)&&(e.length&&(e+="&"),e+=encodeURIComponent(n)+"="+encodeURIComponent(t[n]));return e},e.decode=function(t){for(var e={},n=t.split("&"),r=0,o=n.length;r0);return e}function r(t){var e=0;for(u=0;u';i=document.createElement(e)}catch(t){i=document.createElement("iframe"),i.name=o.iframeId,i.src="javascript:0"}i.id=o.iframeId,o.form.appendChild(i),o.iframe=i}var o=this;if(!this.form){var i,s=document.createElement("form"),a=document.createElement("textarea"),c=this.iframeId="eio_iframe_"+this.index;s.className="socketio",s.style.position="absolute",s.style.top="-1000px",s.style.left="-1000px",s.target=c,s.method="POST",s.setAttribute("accept-charset","utf-8"),a.name="d",s.appendChild(a),document.body.appendChild(s),this.form=s,this.area=a}this.form.action=this.uri(),r(),t=t.replace(u,"\\\n"),this.area.value=t.replace(p,"\\n");try{this.form.submit()}catch(h){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===o.iframe.readyState&&n()}:this.iframe.onload=n}},function(t,e,n){function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.perMessageDeflate=t.perMessageDeflate,this.usingBrowserWebSocket=o&&!t.forceNode,this.protocols=t.protocols,this.usingBrowserWebSocket||(l=i),s.call(this,t)}var o,i,s=n(21),a=n(22),c=n(30),p=n(31),u=n(32),h=n(3)("engine.io-client:websocket");if("undefined"!=typeof WebSocket?o=WebSocket:"undefined"!=typeof self&&(o=self.WebSocket||self.MozWebSocket),"undefined"==typeof window)try{i=n(35)}catch(f){}var l=o||i;t.exports=r,p(r,s),r.prototype.name="websocket",r.prototype.supportsBinary=!0,r.prototype.doOpen=function(){if(this.check()){var t=this.uri(),e=this.protocols,n={};this.isReactNative||(n.agent=this.agent,n.perMessageDeflate=this.perMessageDeflate,n.pfx=this.pfx,n.key=this.key,n.passphrase=this.passphrase,n.cert=this.cert,n.ca=this.ca,n.ciphers=this.ciphers,n.rejectUnauthorized=this.rejectUnauthorized),this.extraHeaders&&(n.headers=this.extraHeaders),this.localAddress&&(n.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket&&!this.isReactNative?e?new l(t,e):new l(t):new l(t,e,n)}catch(r){return this.emit("error",r)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},r.prototype.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.onOpen()},this.ws.onclose=function(){t.onClose()},this.ws.onmessage=function(e){t.onData(e.data)},this.ws.onerror=function(e){t.onError("websocket error",e)}},r.prototype.write=function(t){function e(){n.emit("flush"),setTimeout(function(){n.writable=!0,n.emit("drain")},0)}var n=this;this.writable=!1;for(var r=t.length,o=0,i=r;o0&&t.jitter<=1?t.jitter:0,this.attempts=0}t.exports=n,n.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},n.prototype.reset=function(){this.attempts=0},n.prototype.setMin=function(t){this.ms=t},n.prototype.setMax=function(t){this.max=t},n.prototype.setJitter=function(t){this.jitter=t}}])});
+//# sourceMappingURL=socket.io.js.map
diff --git a/lib/socket.js b/lib/socket.js
index 1fe10ec..214a0d3 100644
--- a/lib/socket.js
+++ b/lib/socket.js
@@ -15,16 +15,13 @@ const ERROR_PERMISSION = 'permissionError';
const COMMAND_RE_AUTHENTICATE = 'reauthenticate';
// From settings used only secure, auth and crossDomain
-function IOSocket(server, settings, adapter, ignore, store) {
+function IOSocket(server, settings, adapter) {
if (!(this instanceof IOSocket)) {
- return new IOSocket(server, settings, adapter, ignore, store);
+ return new IOSocket(server, settings, adapter);
}
- socketio = require('./ws');
+ socketio = require('socket.io');
- store = store || settings.store;
-
- const userKey = 'connect.sid'; // const
this.settings = settings || {};
this.adapter = adapter;
this.webServer = server;
@@ -32,13 +29,9 @@ function IOSocket(server, settings, adapter, ignore, store) {
this.thersholdInterval = null;
let cookieParser;
- let passport;
- let passportSocketIo;
if (settings.auth) {
- cookieParser = require('cookie-parser');
- passport = require('passport');
- passportSocketIo = require('./passportSocket');
+ cookieParser = require('cookie-parser');
}
const that = this;
@@ -56,27 +49,67 @@ function IOSocket(server, settings, adapter, ignore, store) {
// Extract username from socket
function getUserFromSocket(socket, callback) {
let wait = false;
- if (typeof callback !== 'function') {
- return;
- }
-
try {
- if (socket.conn.request.sessionID) {
- socket._sessionID = socket.conn.request.sessionID;
- wait = true;
- if (store) {
- store.get(socket.conn.request.sessionID, (err, obj) => {
- if (obj && obj.passport && obj.passport.user) {
- callback(null, obj.passport.user ? 'system.user.' + obj.passport.user : '');
+ if (socket.handshake.headers.cookie && (!socket.request || !socket.request._query || !socket.request._query.user)) {
+ let cookie = decodeURIComponent(socket.handshake.headers.cookie);
+ let m = cookie.match(/connect\.sid=(.+)/);
+ if (m) {
+ // If session cookie exists
+ let c = m[1].split(';')[0];
+ let sessionID = cookieParser.signedCookie(c, that.settings.secret);
+ if (sessionID) {
+ // Get user for session
+ wait = true;
+ that.settings.store.get(sessionID, (err, obj) => {
+ if (obj && obj.passport && obj.passport.user) {
+ socket._sessionID = sessionID;
+ if (typeof callback === 'function') {
+ callback(null, obj.passport.user);
+ } else {
+ that.adapter.log.warn('[getUserFromSocket] Invalid callback');
+ }
+ } else {
+ if (typeof callback === 'function') {
+ callback('unknown user');
+ } else {
+ that.adapter.log.warn('[getUserFromSocket] Invalid callback')
+ }
+ }
+ });
+ }
+ }
+ }
+
+ if (!wait) {
+ let user = socket.request._query.user;
+ let pass = socket.request._query.pass;
+ if (user && pass) {
+ wait = true;
+ that.adapter.checkPassword(user, pass, (res) => {
+ if (res) {
+ that.adapter.log.debug('Logged in: ' + user);
+ if (typeof callback === 'function') {
+ callback(null, user);
+ } else {
+ that.adapter.log.warn('[getUserFromSocket] Invalid callback')
+ }
+ } else {
+ that.adapter.log.warn(`Invalid password or user name: ${user}, ${pass[0]}***(${pass.length})`);
+ if (typeof callback === 'function') {
+ callback('unknown user');
+ } else {
+ that.adapter.log.warn('[getUserFromSocket] Invalid callback')
+ }
}
});
}
}
} catch (e) {
- // ignore
+ that.adapter.log.error(e);
+ wait = false;
}
- !wait && callback('Cannot detect user');
+ !wait && typeof callback === 'function' && callback('Cannot detect user');
}
function disableEventThreshold(readAll) {
@@ -89,14 +122,14 @@ function IOSocket(server, settings, adapter, ignore, store) {
setTimeout(() => {
if (readAll) {
- that.adapter.getForeignStates('*', ()/*(err, res)*/ => {
+ that.adapter.getForeignStates('*', (err, res) => {
that.adapter.log.info('received all states');
- /*for (let id in res) {
+ for (const id in res) {
if (Object.prototype.hasOwnProperty.call(res, id) && JSON.stringify(states[id]) !== JSON.stringify(res[id])) {
that.server && that.server.sockets && that.server.sockets.emit('stateChange', id, res[id]);
states[id] = res[id];
}
- }*/
+ }
});
}
@@ -124,57 +157,31 @@ function IOSocket(server, settings, adapter, ignore, store) {
function getClientAddress(socket) {
let address;
- if (socket.connection) {
- address = socket.connection && socket.connection.remoteAddress;
- } else {
- address = socket.ws._socket.remoteAddress;
- }
-
- if (!address && socket.handshake) {
+ if (socket.handshake) {
address = socket.handshake.address;
}
- if (!address && socket.conn.request && socket.conn.request.connection) {
- address = socket.conn.request.connection.remoteAddress;
+ if (!address && socket.request && socket.request.connection) {
+ address = socket.request.connection.remoteAddress;
}
return address;
}
- function onAuthorizeSuccess(data, accept) {
- adapter.log.debug('successful connection to socket.io from ' + data.connection.remoteAddress);
- //adapter.log.info(JSON.stringify(data));
-
- accept();
- }
-
- function onAuthorizeFail(data, message, error, accept) {
- setTimeout(() => data.socket.emit(COMMAND_RE_AUTHENTICATE), 100);
-
- error && adapter.log.error(`failed connection to socket.io from ${data.connection.remoteAddress}:`, message);
-
- if (error) {
- accept(new Error(message));
- } else {
- accept(new Error('failed connection to socket.io: ' + message));//null, false);
- }
- // this error will be sent to the user as a special error-package
- // see: http://socket.io/docs/client-api/#socket > error-object
- }
-
- this.initSocket = function (socket, cb) {
+ this.initSocket = function (socket) {
if (!socket._acl) {
if (that.settings.auth) {
getUserFromSocket(socket, (err, user) => {
if (err || !user) {
socket.emit(COMMAND_RE_AUTHENTICATE);
- that.adapter.log.error(`socket.io ${err || 'No user found in cookies'}`);
+ that.adapter.log.error(`socket.io [init] ${err || 'No user found in cookies'}`);
+ socket.disconnect();
} else {
socket._secure = true;
that.adapter.log.debug(`socket.io client ${user} connected`);
- that.adapter.calculatePermissions(user, commandsPermissions, acl => {
+ that.adapter.calculatePermissions(`system.user.${user}`, commandsPermissions, acl => {
const address = getClientAddress(socket);
// socket._acl = acl;
socket._acl = mergeACLs(address, acl, that.settings.whiteListSettings);
- socketEvents(socket, address, cb);
+ socketEvents(socket, address);
});
}
});
@@ -183,12 +190,12 @@ function IOSocket(server, settings, adapter, ignore, store) {
const address = getClientAddress(socket);
// socket._acl = acl;
socket._acl = mergeACLs(address, acl, that.settings.whiteListSettings);
- socketEvents(socket, address, cb);
+ socketEvents(socket, address);
});
}
} else {
const address = getClientAddress(socket);
- socketEvents(socket, address, cb);
+ socketEvents(socket, address);
}
};
@@ -220,7 +227,7 @@ function IOSocket(server, settings, adapter, ignore, store) {
return null;
}
- wildCardIps.forEach(function (ip) {
+ wildCardIps.forEach(ip => {
const ipParts = ip.split('.');
if (ipParts.length === 4) {
for (let i = 0; i < 4; i++) {
@@ -294,9 +301,8 @@ function IOSocket(server, settings, adapter, ignore, store) {
if (socket) {
socket._subscribe = socket._subscribe || {};
}
- if (!this.subscribes[type]) {
- this.subscribes[type] = {};
- }
+
+ this.subscribes[type] = this.subscribes[type] || {};
let s;
if (socket) {
@@ -310,7 +316,7 @@ function IOSocket(server, settings, adapter, ignore, store) {
const p = pattern2RegEx(pattern);
if (p === null) {
- return this.adapter.log.warn('Empty pattern!');
+ return this.adapter.log.warn('Empty pattern on subscribe!');
}
if (socket) {
s.push({pattern: pattern, regex: new RegExp(p)});
@@ -325,9 +331,7 @@ function IOSocket(server, settings, adapter, ignore, store) {
this.adapter.subscribeForeignObjects(pattern);
}
} else if (type === 'log') {
- if (this.adapter.requireLog) {
- this.adapter.requireLog(true);
- }
+ this.adapter.requireLog && this.adapter.requireLog(true);
}
} else {
this.subscribes[type][pattern]++;
@@ -349,9 +353,7 @@ function IOSocket(server, settings, adapter, ignore, store) {
this.unsubscribe = function (socket, type, pattern) {
//console.log((socket._name || socket.id) + ' unsubscribe ' + pattern);
- if (!this.subscribes[type]) {
- this.subscribes[type] = {};
- }
+ this.subscribes[type] = this.subscribes[type] || {};
if (socket) {
if (!socket._subscribe || !socket._subscribe[type]) {
@@ -359,7 +361,6 @@ function IOSocket(server, settings, adapter, ignore, store) {
}
for (let i = socket._subscribe[type].length - 1; i >= 0; i--) {
if (socket._subscribe[type][i].pattern === pattern) {
-
// Remove pattern from global list
if (this.subscribes[type][pattern] !== undefined) {
this.subscribes[type][pattern]--;
@@ -369,14 +370,10 @@ function IOSocket(server, settings, adapter, ignore, store) {
this.adapter.unsubscribeForeignStates(pattern);
} else if (type === 'objectChange') {
//console.log((socket._name || socket.id) + ' unsubscribeForeignObjects ' + pattern);
- if (this.adapter.unsubscribeForeignObjects) {
- this.adapter.unsubscribeForeignObjects(pattern);
- }
+ this.adapter.unsubscribeForeignObjects && this.adapter.unsubscribeForeignObjects(pattern);
} else if (type === 'log') {
//console.log((socket._name || socket.id) + ' requireLog false');
- if (this.adapter.requireLog) {
- this.adapter.requireLog(false);
- }
+ this.adapter.requireLog && this.adapter.requireLog(false);
}
delete this.subscribes[type][pattern];
}
@@ -397,14 +394,10 @@ function IOSocket(server, settings, adapter, ignore, store) {
this.adapter.unsubscribeForeignStates(pattern);
} else if (type === 'objectChange') {
//console.log((socket._name || socket.id) + ' unsubscribeForeignObjects ' + pattern);
- if (this.adapter.unsubscribeForeignObjects) {
- this.adapter.unsubscribeForeignObjects(pattern);
- }
+ this.adapter.unsubscribeForeignObjects && this.adapter.unsubscribeForeignObjects(pattern);
} else if (type === 'log') {
//console.log((socket._name || socket.id) + ' requireLog false');
- if (this.adapter.requireLog) {
- this.adapter.requireLog(false);
- }
+ this.adapter.requireLog && this.adapter.requireLog(false);
}
delete this.subscribes[type][pattern];
}
@@ -419,14 +412,10 @@ function IOSocket(server, settings, adapter, ignore, store) {
this.adapter.unsubscribeForeignStates(pattern);
} else if (type === 'objectChange') {
//console.log((socket._name || socket.id) + ' unsubscribeForeignObjects ' + pattern);
- if (this.adapter.unsubscribeForeignObjects) {
- this.adapter.unsubscribeForeignObjects(pattern);
- }
+ this.adapter.unsubscribeForeignObjects && this.adapter.unsubscribeForeignObjects(pattern);
} else if (type === 'log') {
//console.log((socket._name || socket.id) + ' requireLog false');
- if (this.adapter.requireLog) {
- this.adapter.requireLog(false);
- }
+ this.adapter.requireLog && this.adapter.requireLog(false);
}
delete this.subscribes[type][pattern];
}
@@ -458,13 +447,9 @@ function IOSocket(server, settings, adapter, ignore, store) {
if (type === 'stateChange') {
that.adapter.unsubscribeForeignStates(pattern);
} else if (type === 'objectChange') {
- if (that.adapter.unsubscribeForeignObjects) {
- that.adapter.unsubscribeForeignObjects(pattern);
- }
+ that.adapter.unsubscribeForeignObjects && that.adapter.unsubscribeForeignObjects(pattern);
} else if (type === 'log') {
- if (that.adapter.requireLog) {
- that.adapter.requireLog(false);
- }
+ that.adapter.requireLog && that.adapter.requireLog(false);
}
delete that.subscribes[type][pattern];
}
@@ -485,13 +470,9 @@ function IOSocket(server, settings, adapter, ignore, store) {
if (type === 'stateChange') {
that.adapter.subscribeForeignStates(pattern);
} else if (type === 'objectChange') {
- if (that.adapter.subscribeForeignObjects) {
- that.adapter.subscribeForeignObjects(pattern);
- }
+ that.adapter.subscribeForeignObjects && that.adapter.subscribeForeignObjects(pattern);
} else if (type === 'log') {
- if (that.adapter.requireLog) {
- that.adapter.requireLog(true);
- }
+ that.adapter.requireLog && that.adapter.requireLog(true);
}
} else {
that.subscribes[type][pattern]++;
@@ -506,58 +487,36 @@ function IOSocket(server, settings, adapter, ignore, store) {
const s = socket._subscribe[type];
for (let i = 0; i < s.length; i++) {
if (s[i].regex.test(id)) {
- return socket.emit(type, id, obj);
+ updateSession(socket);
+ socket.emit(type, id, obj);
+ return;
}
}
}
- function waitForSessionEnd(socket) {
- if (socket._sessionTimer) {
- clearTimeout(socket._sessionTimer);
- socket._sessionTimer = null;
- }
- const sessionId = socket._sessionID;
- store && store.get(sessionId, (err, obj) => {
- if (obj) {
- const expires = new Date(obj.cookie.expires);
- const interval = expires.getTime() - Date.now();
- if (interval > 0) {
- socket._sessionTimer = socket._sessionTimer || setTimeout(() => waitForSessionEnd(socket), interval > 3600000 ? 3600000 : interval);
- socket.emit('expire', expires.getTime());
- } else {
- adapter.log.warn('REAUTHENTICATE!');
- socket.emit(COMMAND_RE_AUTHENTICATE);
- }
- } else {
- adapter.log.warn('REAUTHENTICATE!');
- socket && socket.emit && socket.emit(COMMAND_RE_AUTHENTICATE);
- }
- });
- }
-
// update session ID, but not ofter than 60 seconds
function updateSession(socket) {
- const sessionId = socket._sessionID;
- const now = Date.now();
- if (sessionId && (!socket._lastUpdate || now - socket._lastUpdate > 10000)) {
- socket._lastUpdate = now;
- store && store.get(sessionId, (err, obj) => {
- // obj = {"cookie":{"originalMaxAge":2592000000,"expires":"2020-09-24T18:09:50.377Z","httpOnly":true,"path":"/"},"passport":{"user":"admin"}}
- if (obj) {
- // start timer
- !socket._sessionTimer && waitForSessionEnd(socket);
- /*obj.ttl = obj.ttl || (new Date(obj.cookie.expires).getTime() - now);
- const expires = new Date();
- expires.setMilliseconds(expires.getMilliseconds() + obj.ttl + 10000);
- obj.cookie.expires = expires.toISOString();
- console.log('Session ' + sessionId + ' expires on ' + obj.cookie.expires);
-
- store.set(sessionId, obj);*/
- } else {
- adapter.log.warn('REAUTHENTICATE!');
- socket.emit(COMMAND_RE_AUTHENTICATE);
- }
- });
+ if (socket._sessionID) {
+ let time = Date.now();
+ if (socket._lastActivity && time - socket._lastActivity > settings.ttl * 1000) {
+ socket.emit(COMMAND_RE_AUTHENTICATE);
+ socket.disconnect();
+ return false;
+ }
+ socket._lastActivity = time;
+ if (!socket._sessionTimer) {
+ socket._sessionTimer = setTimeout(() => {
+ socket._sessionTimer = null;
+ that.settings.store.get(socket._sessionID, (err, obj) => {
+ if (obj) {
+ that.adapter.setSession(socket._sessionID, settings.ttl, obj);
+ } else {
+ socket.emit(COMMAND_RE_AUTHENTICATE);
+ socket.disconnect();
+ }
+ });
+ }, 60000);
+ }
}
return true;
}
@@ -754,10 +713,10 @@ function IOSocket(server, settings, adapter, ignore, store) {
} else {
if (commandsPermissions[command]) {
socket.emit(ERROR_PERMISSION, {
- command: command,
+ command,
type: commandsPermissions[command].type,
operation: commandsPermissions[command].operation,
- arg: arg
+ arg
});
} else {
socket.emit(ERROR_PERMISSION, {command, arg});
@@ -807,13 +766,13 @@ function IOSocket(server, settings, adapter, ignore, store) {
function stopAdapter(reason, callback) {
reason && that.adapter.log.warn('Adapter stopped. Reason: ' + reason);
- that.adapter.getForeignObject('system.adapter.' + that.adapter.namespace, function (err, obj) {
- err && that.adapter.log.error('[getForeignObject]: ' + err);
+ that.adapter.getForeignObject('system.adapter.' + that.adapter.namespace, (err, obj) => {
+ err && that.adapter.log.error('[stopAdapter/getForeignObject]: ' + err);
if (obj) {
obj.common.enabled = false;
setTimeout(() => {
that.adapter.setForeignObject(obj._id, obj, err => {
- err && that.adapter.log.error('[setForeignObject]: ' + err);
+ err && that.adapter.log.error('[stopAdapter/setForeignObject]: ' + err);
callback && callback();
});
}, 5000);
@@ -827,16 +786,14 @@ function IOSocket(server, settings, adapter, ignore, store) {
if (!url) {
that.adapter.log.warn('Received redirect command, but no URL');
} else {
- that.adapter.getForeignObject('system.adapter.' + that.adapter.namespace, function (err, obj) {
+ that.adapter.getForeignObject('system.adapter.' + that.adapter.namespace, (err, obj) => {
err && that.adapter.log.error('redirectAdapter [getForeignObject]: ' + err);
if (obj) {
obj.native.cloudUrl = url;
- setTimeout(() => {
- that.adapter.setForeignObject(obj._id, obj, err => {
- err && that.adapter.log.error('redirectAdapter [setForeignObject]: ' + err);
- callback && callback();
- });
- }, 3000);
+ setTimeout(() => that.adapter.setForeignObject(obj._id, obj, err => {
+ err && that.adapter.log.error('redirectAdapter [setForeignObject]: ' + err);
+ callback && callback();
+ }), 3000);
} else {
callback && callback();
}
@@ -848,7 +805,7 @@ function IOSocket(server, settings, adapter, ignore, store) {
that.emit && that.emit('connectWait', delaySeconds);
}
- function socketEvents(socket, address, cb) {
+ function socketEvents(socket, address) {
if (socket.conn) {
that.adapter.log.info(`==> Connected ${socket._acl.user} from ${address}`);
} else {
@@ -1478,11 +1435,6 @@ function IOSocket(server, settings, adapter, ignore, store) {
unsubscribeSocket(this, 'log');
that.infoTimeout = that.infoTimeout || setTimeout(updateConnectedInfo, 1000);
- if (socket._sessionTimer) {
- clearTimeout(socket._sessionTimer);
- socket._sessionTimer = null;
- }
-
// if client mode
if (!socket.conn) {
socket._apiKeyOk = false;
@@ -1598,12 +1550,13 @@ function IOSocket(server, settings, adapter, ignore, store) {
});
if (socket._sessionID) {
- that.adapter.getSession(socket._sessionID, function (obj) {
+ that.adapter.getSession(socket._sessionID, obj => {
if (obj && obj.passport) {
socket._acl.user = obj.passport.user;
} else {
socket._acl.user = '';
socket.emit(COMMAND_RE_AUTHENTICATE);
+ socket.disconnect();
}
if (socket._authPending) {
socket._authPending(!!socket._acl.user, true);
@@ -1634,13 +1587,15 @@ function IOSocket(server, settings, adapter, ignore, store) {
});*/
} else {
// if server mode
- if (socket._sessionID && adapter.config.auth) {
+ if (socket.conn.request.sessionID) {
socket._secure = true;
+ socket._sessionID = socket.conn.request.sessionID;
// Get user for session
- store && store.get(socket._sessionID, (err, obj) => {
+ that.settings.store.get(socket.conn.request.sessionID, (err, obj) => {
if (!obj || !obj.passport) {
socket._acl.user = '';
socket.emit(COMMAND_RE_AUTHENTICATE);
+ socket.disconnect();
}
if (socket._authPending) {
socket._authPending(!!socket._acl.user, true);
@@ -1653,8 +1608,6 @@ function IOSocket(server, settings, adapter, ignore, store) {
subscribeSocket(socket, 'objectChange');
subscribeSocket(socket, 'log');
}
-
- cb && cb();
}
function updateConnectedInfo() {
@@ -1717,7 +1670,7 @@ function IOSocket(server, settings, adapter, ignore, store) {
(function __constructor() {
if (that.settings.allowAdmin) {
// detect event bursts
- that.thersholdInterval = setInterval(function () {
+ that.thersholdInterval = setInterval(() => {
if (!eventsThreshold.active) {
if (eventsThreshold.count > eventsThreshold.value) {
eventsThreshold.accidents++;
@@ -1780,6 +1733,9 @@ function IOSocket(server, settings, adapter, ignore, store) {
path.resolve = pathResolve; // restore path.resolve once done
that.webServer.__inited = true;
}
+
+ // force using only websockets
+ that.settings.forceWebSockets && that.server.set('transports', ['websocket']);
} else {
that.server = server;
}
@@ -1791,15 +1747,36 @@ function IOSocket(server, settings, adapter, ignore, store) {
}
if (that.settings.auth && that.server) {
- that.server.use(passportSocketIo.authorize({
- passport,
- cookieParser,
- key: userKey, // the name of the cookie where express/connect stores its session_id
- secret: settings.secret, // the session_secret to parse the cookie
- store, // we NEED to use a sessionstore. no memorystore please
- success: onAuthorizeSuccess, // *optional* callback on success - read more below
- fail: onAuthorizeFail // *optional* callback on fail/error - read more below
- }));
+ that.server.use((socket, next) => {
+ if (!socket.request._query.user || !socket.request._query.pass) {
+ getUserFromSocket(socket, (err, user) => {
+ if (err || !user) {
+ socket.emit(COMMAND_RE_AUTHENTICATE);
+ that.adapter.log.error(`socket.io [use] ${err || 'User not found'}`);
+ socket.disconnect();
+ } else {
+ socket._secure = true;
+ that.adapter.calculatePermissions(`system.user.${user}`, commandsPermissions, acl => {
+ let address = getClientAddress(socket);
+ // socket._acl = acl;
+ socket._acl = mergeACLs(address, acl, that.settings.whiteListSettings);
+ next();
+ });
+ }
+ });
+ } else {
+ that.adapter.checkPassword(socket.request._query.user, socket.request._query.pass, res => {
+ if (res) {
+ that.adapter.log.debug(`Logged in: ${socket.request._query.user}, ${socket.request._query.pass}`);
+ next();
+ } else {
+ that.adapter.log.warn(`Invalid password or user name: ${socket.request._query.user}, ${socket.request._query.pass}`);
+ socket.emit(COMMAND_RE_AUTHENTICATE);
+ next(new Error('Invalid password or user name'));
+ }
+ });
+ }
+ });
}
// Enable cross domain access
@@ -1810,15 +1787,13 @@ function IOSocket(server, settings, adapter, ignore, store) {
that.settings.ttl = that.settings.ttl || 3600;
that.server.on('connection', that.initSocket);
- that.server.on('error', e => that.adapter.log.error('Server error: ' + e));
+ that.server.on('error', (e, details) => that.adapter.log.error(`Server error: ${e}${details ? ' - ' + details : ''}`));
if (settings.port) {
that.adapter.log.info(`${settings.secure ? 'Secure ' : ''}socket.io server listening on port ${settings.port}`);
}
- if (!that.infoTimeout) {
- that.infoTimeout = setTimeout(updateConnectedInfo, 1000);
- }
+ that.infoTimeout = that.infoTimeout || setTimeout(updateConnectedInfo, 1000);
// if client mode => add event handlers
if (that.settings.apikey) {
diff --git a/lib/ws.js b/lib/ws.js
deleted file mode 100644
index 4338797..0000000
--- a/lib/ws.js
+++ /dev/null
@@ -1,343 +0,0 @@
-/* jshint -W097 */
-/* jshint strict: false */
-/* jslint node: true */
-/* jshint -W061 */
-'use strict';
-
-const WebSocket = require('ws');
-const querystring = require('querystring');
-
-const MESSAGE_TYPES = {
- MESSAGE: 0,
- PING: 1,
- PONG: 2,
- CALLBACK: 3
-};
-
-const DEBUG = false;
-
-function Socket(ws, sessionID, name) {
- this.ws = ws;
- const handlers = {};
- let lastPong = Date.now();
- let id = 0;
-
- this._name = name;
-
- // simulate interface of socket.io
- this.conn = {
- request: { sessionID }
- };
-
- this.id = sessionID;
-
- let pingInterval = setInterval(() => {
- if (Date.now() - lastPong > 5000) {
- ws.send(JSON.stringify([MESSAGE_TYPES.PING]));
- }
- if (Date.now() - lastPong > 15000) {
- this.close();
- }
- }, 5000);
-
- this.on = (name, cb) => {
- if (cb) {
- handlers[name] = handlers[name] || [];
- handlers[name].push(cb);
- }
- };
-
- this.off = (name, cb) => {
- if (handlers[name]) {
- const pos = handlers[name].indexOf(cb);
- if (pos !== -1) {
- handlers[name].splice(pos, 1);
- if (!handlers[name].length) {
- delete handlers[name];
- }
- }
- }
- };
-
- this.emit = (name, arg1, arg2, arg3, arg4, arg5) => {
- id++;
- if (arg1 === undefined && arg2 === undefined && arg3 === undefined && arg4 === undefined && arg5 === undefined) {
- this.ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, id, name]));
- } else if (arg2 === undefined && arg3 === undefined && arg4 === undefined && arg5 === undefined) {
- this.ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, id, name, [arg1]]));
- } else if (arg3 === undefined && arg4 === undefined && arg5 === undefined) {
- this.ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, id, name, [arg1, arg2]]));
- } else if (arg4 === undefined && arg5 === undefined) {
- this.ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, id, name, [arg1, arg2, arg3]]));
- } else if (arg5 === undefined) {
- this.ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, id, name, [arg1, arg2, arg3, arg4]]));
- } else {
- this.ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, id, name, [arg1, arg2, arg3, arg4, arg5]]));
- }
- };
-
- this.responseWithCallback = (name, id, arg1, arg2, arg3, arg4, arg5) => {
- let args;
-
- // error cannot be converted normally, so try to use internal function for it
- if (arg1 && arg1 instanceof Error) {
- arg1 = arg1.toString();
- }
-
- if (arg1 === undefined && arg2 === undefined && arg3 === undefined && arg4 === undefined && arg5 === undefined) {
- return ws.send(JSON.stringify([MESSAGE_TYPES.CALLBACK, id, name]));
- } else if (arg2 === undefined && arg3 === undefined && arg4 === undefined && arg5 === undefined) {
- args = [arg1];
- } else if (arg3 === undefined && arg4 === undefined && arg5 === undefined) {
- args = [arg1, arg2];
- } else if (arg4 === undefined && arg5 === undefined) {
- args = [arg1, arg2, arg3];
- } else if (arg5 === undefined) {
- args = [arg1, arg2, arg3, arg4];
- } else {
- args = [arg1, arg2, arg3, arg4, arg5];
- }
-
- ws.send(JSON.stringify([MESSAGE_TYPES.CALLBACK, id, name, args]));
- };
-
- this.withCallback = (name, id, args) => {
- if (!args || !args.length) {
- setImmediate(() =>
- handlers[name] && handlers[name].forEach(cb => cb.call(this, (arg1, arg2, arg3, arg4, arg5) =>
- this.responseWithCallback(name, id, arg1, arg2, arg3, arg4, arg5))));
- } else if (args.length === 1) {
- setImmediate(() =>
- handlers[name] && handlers[name].forEach(cb => cb.call(this, args[0], (arg1, arg2, arg3, arg4, arg5) =>
- this.responseWithCallback(name, id, arg1, arg2, arg3, arg4, arg5))));
- } else if (args.length === 2) {
- setImmediate(() =>
- handlers[name] && handlers[name].forEach(cb => cb.call(this, args[0], args[1], (arg1, arg2, arg3, arg4, arg5) =>
- this.responseWithCallback(name, id, arg1, arg2, arg3, arg4, arg5))));
- } else if (args.length === 3) {
- setImmediate(() =>
- handlers[name] && handlers[name].forEach(cb => cb.call(this, args[0], args[1], args[2], (arg1, arg2, arg3, arg4, arg5) =>
- this.responseWithCallback(name, id, arg1, arg2, arg3, arg4, arg5))));
- } else if (args.length === 4) {
- setImmediate(() =>
- handlers[name] && handlers[name].forEach(cb => cb.call(this, args[0], args[1], args[2], args[3], (arg1, arg2, arg3, arg4, arg5) =>
- this.responseWithCallback(name, id, arg1, arg2, arg3, arg4, arg5))));
- } else {
- setImmediate(() =>
- handlers[name] && handlers[name].forEach(cb => cb.call(this, args[0], args[1], args[2], args[3], args[4], (arg1, arg2, arg3, arg4, arg5) =>
- this.responseWithCallback(name, id, arg1, arg2, arg3, arg4, arg5))));
- }
- };
-
- ws.on('message', (data, isBinary) => {
- lastPong = Date.now();
- let message = isBinary ? data : data.toString();
-
- if (!message || typeof message !== 'string') {
- return console.error('Received invalid message: ' + JSON.stringify(message));
- }
- try {
- message = JSON.parse(message);
- } catch (e) {
- return console.error('Received invalid message: ' + JSON.stringify(message));
- }
- const [type, id, name, args] = message;
-
- if (type === MESSAGE_TYPES.CALLBACK) {
- DEBUG && console.log(name);
- handlers[name] && this.withCallback(name, id, args);
- } else
- if (type === MESSAGE_TYPES.MESSAGE) {
- DEBUG && console.log(name);
- handlers[name] && setImmediate(() => handlers[name] && handlers[name].forEach(cb => cb.call(this, args[0], args[1], args[2], args[3], args[4])));
- } else if (type === MESSAGE_TYPES.PING) {
- ws.send(JSON.stringify([MESSAGE_TYPES.PONG]));
- } else if (type === MESSAGE_TYPES.PONG) {
- // lastPong saved
- } else {
- console.log('Received unknown message type: ' + type);
- }
- });
-
- this.close = () => {
- pingInterval && clearInterval(pingInterval);
- pingInterval = null;
-
- handlers.disconnect && handlers.disconnect.forEach(cb => cb.apply(this));
-
- Object.keys(handlers).forEach(name => handlers[name] = undefined);
-
- try {
- ws.close();
- } catch (e) {
- // ignore
- }
- };
-}
-
-function SocketIO (server) {
- const handlers = {};
- const run = [];
-
- const socketsList = [];
-
- const wss = new WebSocket.Server({
- server,
- verifyClient: function (info, done) {
- if (run.length) {
- run.forEach(cb => cb(info.req, err => {
- if (err) {
- info.req._wsNotAuth = true;
- }
- done && done(true);
- done = null;
- }));
- } else {
- done && done(true);
- done = null;
- }
- },
- perMessageDeflate: {
- zlibDeflateOptions: {
- chunkSize: 1024,
- memLevel: 9,
- level: 9
- },
- zlibInflateOptions: {
- chunkSize: 16 * 1024
- },
- clientNoContextTakeover: true,
- serverNoContextTakeover: true
- }
- });
-
- wss.on('connection', (ws, request) => {
- DEBUG && console.log('connected');
-
- if (!request) {
- console.error('Unexpected behaviour: request is NULL!');
- }
-
- if (request && request._wsNotAuth) {
- const ip = request.headers['x-forwarded-for'] ||
- request.connection.remoteAddress ||
- request.socket.remoteAddress ||
- (request.connection.socket ? request.connection.socket.remoteAddress : null);
- handlers.error && handlers.error.forEach(cb => cb('error', `authentication failed for ${ip}`));
- ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, 401, 'reauthenticate']));
- setTimeout(() =>
- ws && ws.destroy && ws.destroy(), 500);
- } else {
- let query;
-
- try {
- if (request) {
- const queryString = request.url.split('?')[1];
- query = querystring.parse(queryString || '');
- }
- } catch (e) {
- query = null;
- }
-
- if (query && query.sid) {
- const socket = new Socket(ws, request.sessionID || query.sid, query.name);
- socket.query = query;
- socketsList.push(socket);
- this.sockets.engine.clientsCount = socketsList.length;
-
- ws.on('close', () => {
- DEBUG && console.log('closed');
- let i;
- for (i = 0; i < socketsList.length; i++) {
- if (socketsList[i].ws === ws) {
- socketsList[i].close();
- socketsList.splice(i, 1);
- this.sockets.engine.clientsCount = socketsList.length;
- return;
- }
- }
- });
-
- // install handlers
- if (handlers.connection && handlers.connection.length) {
- // we have a race condition here.
- // If the user is not admin it will be requested for him the rights and no handlers will be installed.
- // So we must be sure, that all event handlers are installed before sending ___ready___.
- let timeout = setTimeout(() => {
- timeout = null;
- socket.emit('___ready___');
- console.warn('Sent ready, but not all handlers installed!');
- }, 1500); // TODO, This parameter must be configurable
-
- handlers.connection.forEach(cb => cb(socket, () => {
- if (timeout) {
- clearTimeout(timeout);
- timeout = null;
- // say to client we are ready
- socket.emit('___ready___');
- }
- }));
- } else {
- socket.emit('___ready___');
- }
- } else {
- if (request) {
- const ip = request.headers['x-forwarded-for'] ||
- request.connection.remoteAddress ||
- request.socket.remoteAddress ||
- (request.connection.socket ? request.connection.socket.remoteAddress : null);
-
- handlers.error && handlers.error.forEach(cb => cb('error', 'No sid found from ' + ip));
- } else {
- handlers.error && handlers.error.forEach(cb => cb('error', 'No sid found'));
- }
-
- ws.send(JSON.stringify([MESSAGE_TYPES.MESSAGE, 501, 'error', ['invalid sid']]));
- setTimeout(() =>
- ws && ws.destroy && ws.destroy(), 500);
- }
- }
- });
-
- this.on = (name, cb) => {
- if (cb) {
- handlers[name] = handlers[name] || [];
- handlers[name].push(cb);
- }
- };
-
- this.off = (name, cb) => {
- if (handlers[name]) {
- const pos = handlers[name].indexOf(cb);
- if (pos !== -1) {
- handlers[name].splice(pos, 1);
- if (!handlers[name].length) {
- delete handlers[name];
- }
- }
- }
- };
-
- this.sockets = {
- connected: socketsList,
- emit: (arg1, arg2, arg3, arg4, arg5) =>
- socketsList.forEach(socket =>
- socket.emit(arg1, arg2, arg3, arg4, arg5)),
- engine: {
- clientsCount: 0
- }
- };
-
- this.engine = this.sockets.engine;
-
- this.use = cb => {
- run.push(cb);
- return this;
- };
-
- this.ioBroker = true;
-}
-
-module.exports = {
- listen: server => new SocketIO(server)
-};
diff --git a/main.js b/main.js
index cf480b6..6485f17 100644
--- a/main.js
+++ b/main.js
@@ -95,7 +95,6 @@ function main() {
// "bind": "0.0.0.0", // "::"
//}
function initWebServer(settings) {
-
const server = {
app: null,
server: null,
diff --git a/package.json b/package.json
index 6b76824..b6dd893 100644
--- a/package.json
+++ b/package.json
@@ -16,17 +16,18 @@
"url": "https://github.com/ioBroker/ioBroker.socketio"
},
"dependencies": {
+ "@iobroker/adapter-core": "^2.5.1",
"axios": "^0.25.0",
"cookie-parser": "^1.4.6",
- "passport": "^0.5.2",
"express-session": "^1.17.2",
- "@iobroker/adapter-core": "^2.5.1",
- "ws": "^8.4.2"
+ "passport": "^0.5.2",
+ "socket.io": "^2.4.1"
},
"devDependencies": {
"@alcalzone/release-script": "^3.5.0",
"@alcalzone/release-script-plugin-iobroker": "^3.5.1",
"@alcalzone/release-script-plugin-license": "^3.5.0",
+ "socket.io-client": "^2.4.0",
"gulp": "^4.0.2",
"mocha": "^9.2.0",
"chai": "^4.3.6"
@@ -44,6 +45,7 @@
],
"scripts": {
"test": "node node_modules/mocha/bin/mocha --exit",
+ "build": "node node_modules/gulp/bin/gulp.js",
"release": "release-script",
"release-patch": "release-script patch --yes",
"release-minor": "release-script minor --yes",