@@ -22,8 +22,7 @@
|
||||
"author": "ale",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-xmpp-server": "^3.0.0",
|
||||
"ltx": "^3.0.0",
|
||||
"ltx": "^3.1.2",
|
||||
"express": "^4.18.2",
|
||||
"ws": "^8.14.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
const net = require('net');
|
||||
const tls = require('tls');
|
||||
const EventEmitter = require('events');
|
||||
const { Connection } = require('node-xmpp-server');
|
||||
const Logger = require('../utils/logger');
|
||||
const XMPPStream = require('./xmpp-stream');
|
||||
|
||||
|
||||
@@ -4,11 +4,100 @@
|
||||
*/
|
||||
|
||||
const EventEmitter = require('events');
|
||||
const { StreamParser } = require('node-xmpp-server');
|
||||
const ltx = require('ltx');
|
||||
const Logger = require('../utils/logger');
|
||||
const crypto = require('crypto');
|
||||
|
||||
// Simple XML stream parser
|
||||
class StreamParser extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.buffer = '';
|
||||
this.depth = 0;
|
||||
this.streamStarted = false;
|
||||
}
|
||||
|
||||
write(data) {
|
||||
this.buffer += data.toString();
|
||||
this.parse();
|
||||
}
|
||||
|
||||
parse() {
|
||||
// Find complete stanzas in buffer
|
||||
let startIdx = 0;
|
||||
let inTag = false;
|
||||
let tagDepth = 0;
|
||||
|
||||
for (let i = 0; i < this.buffer.length; i++) {
|
||||
const char = this.buffer[i];
|
||||
|
||||
if (char === '<') {
|
||||
if (this.buffer.substring(i, i + 2) === '</') {
|
||||
// Closing tag
|
||||
tagDepth--;
|
||||
} else if (this.buffer[i + 1] !== '!' && this.buffer[i + 1] !== '?') {
|
||||
// Opening tag
|
||||
if (!this.streamStarted && this.buffer.substring(i).match(/^<stream:stream/)) {
|
||||
// Parse stream start
|
||||
const streamEndIdx = this.buffer.indexOf('>', i);
|
||||
if (streamEndIdx !== -1) {
|
||||
const streamTag = this.buffer.substring(i, streamEndIdx + 1);
|
||||
try {
|
||||
const attrs = this.parseAttributes(streamTag);
|
||||
this.streamStarted = true;
|
||||
this.emit('streamStart', attrs);
|
||||
this.buffer = this.buffer.substring(streamEndIdx + 1);
|
||||
i = -1;
|
||||
startIdx = 0;
|
||||
} catch (e) {
|
||||
this.emit('error', e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tagDepth++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tagDepth > 0) {
|
||||
inTag = true;
|
||||
}
|
||||
} else if (char === '>' && inTag) {
|
||||
tagDepth--;
|
||||
|
||||
if (tagDepth === 0) {
|
||||
// Complete stanza
|
||||
const stanzaStr = this.buffer.substring(startIdx, i + 1);
|
||||
if (stanzaStr.trim()) {
|
||||
try {
|
||||
const stanza = ltx.parse(stanzaStr);
|
||||
this.emit('stanza', stanza);
|
||||
} catch (e) {
|
||||
this.emit('error', e);
|
||||
}
|
||||
}
|
||||
startIdx = i + 1;
|
||||
inTag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.buffer = this.buffer.substring(startIdx);
|
||||
}
|
||||
|
||||
parseAttributes(tagStr) {
|
||||
const attrs = {};
|
||||
const attrRegex = /(\w+)=['"]([^'"]*)['"]/g;
|
||||
let match;
|
||||
|
||||
while ((match = attrRegex.exec(tagStr)) !== null) {
|
||||
attrs[match[1]] = match[2];
|
||||
}
|
||||
|
||||
return attrs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class XMPPStream extends EventEmitter {
|
||||
constructor(socket, options) {
|
||||
super();
|
||||
|
||||
Referencia en una nueva incidencia
Block a user