Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-12-27 03:44:21 +01:00
padre 74d5e0a94c
commit d41701664d
Se han modificado 3 ficheros con 91 adiciones y 4 borrados

Ver fichero

@@ -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",

Ver fichero

@@ -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');

Ver fichero

@@ -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();