Mercurial > psgxs
view psgxs.js @ 56:99bd1d1ac071
Migration to node-xmpp, done!
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Wed, 10 Aug 2011 15:11:22 -0700 |
parents | 0d3f18bb1d36 |
children | addbf6bbfaa8 |
line wrap: on
line source
#!/usr/bin/env node /* * Copyright (C) 2010 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> * * This file is part of PSĜS, a PubSub server written in JavaScript. * * PSĜS is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License. * * PSĜS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with PSĜS. If not, see <http://www.gnu.org/licenses/>. */ //'use strict'; var config = require('./configuration'); var xmpp = require('node-xmpp'); var conn = new xmpp.Component({ jid: config.jid, password: config.password, host: 'localhost', port: 5347 }); if (config.debug) (function() { var send = conn.send; conn.send = function(s) { console.log('Sent: [1;32m' + s + '[0m'); send.call(conn, s); }; })(); conn.on('stanza', function (stanza) { if (config.debug) console.log('Recv: [1;34m' + stanza + '[0m'); if (stanza.is('iq')) onIq(stanza); else if (stanza.is('message')) onMessage(stanza); else if (stanza.is('presence')) onPresence(stanza); }); conn._uniqueId = 42; conn.getUniqueId = function(suffix) { return ++this._uniqueId + (suffix?(":"+suffix):""); }; var Element = xmpp.Element; Element.prototype.getAttribute = function(name) { return this.attrs[name]; }; require('./iso8601'); var storage = require('./storage'); var errors = require('./errors'); var makeError = errors.makeError; var forms = require('./forms'); var notifs = require('./notifs'); notifs.setConnection(conn); var modules = require('./modules'); function _(obj, color) { var str = require('sys').inspect(obj, false, null); if (color) console.log('\x1b['+c+';1m' + str + '\x1b[0m'); else console.log(str); }; process.addListener('uncaughtException', function (err) { console.log('\x1b[41;1mUncaught exception (' + err + '), this should never happen:\x1b[0m\n' + err.stack); }); function onIq(stanza) { var type = stanza.getAttribute('type'); var from = stanza.getAttribute('to'); var to = stanza.getAttribute('from'); var id = stanza.getAttribute('id'); var response; if (id) response = new Element('iq', {to: to, from: from, type: 'result', id: id}); else response = new Element('iq', {to: to, from: from, type: 'result'}); var send = {}; if (stanza.children.length != 1) return makeError(response, errors.bad_request.n); var payload = stanza.children[0]; var tag = payload.name; var ns = payload.attrs.xmlns; var contents = payload.children; if (tag == 'pubsub') { for (var j in contents) { var child = contents[j]; for (var k in modules) { var module = modules[k]; if (module.stanza && (module.stanza != 'iq')) continue; if (module.type && (module.type != type)) continue; if (module.child && (module.child != tag)) continue; if (module.ns && (module.ns != child.getNS())) continue; if (module.child2 && (module.child2 != child.name)) continue; if (module.number && (module.number != k)) continue; send.response = module.func(response, stanza, payload, to, from); if (send.response) { response = send.response; send.good = true; delete send.response; } } } } else { for (var k in modules) { var module = modules[k]; if (module.stanza && (module.stanza != 'iq')) continue; if (module.type && (module.type != type)) continue; if (module.child && (module.child != tag)) continue; if (module.ns && (module.ns != ns)) continue; if (module.number && (module.number != k)) continue; send.response = module.func(response, stanza, payload, to, from); if (send.response) { response = send.response; send.good = true; delete send.response; } } } conn.send(send.good? response: makeError(response, errors.feature_not_implemented.n)); } function onMessage(stanza) { var from = stanza.getAttribute('to'); var to = stanza.getAttribute('from'); var id = stanza.getAttribute('id'); var response; if (id) response = new Element('message', {to: to, from: from, id: id}); else response = new Element('message', {to: to, from: from}); var send = false; for (var i in stanza.children) { var child = stanza.children[i]; for (var k in modules) { var module = modules[k]; if (module.stanza !== 'message') continue; if (module.type && (module.type != type)) continue; if (module.child && (module.child != child.name)) continue; if (module.ns && (module.ns != child.attrs.xmlns)) continue; if (module.number && (module.number != k)) continue; send.response = module.func(response, stanza, child, to, from); if (send.response) { response = send.response; send.good = true; delete send.response; } } } conn.send(send.good? response: makeError(response, errors.feature_not_implemented.n)); return; var x = stanza.getChild('x', 'jabber:x:data'); if (x) { var form = forms.parse(x); if (form.type == 'submit' && form.fields.FORM_TYPE.value == 'subscribe_authorization') { if (form.fields.subid && form.fields.subid.value) var subID = form.fields.subid.value; if (form.fields.node && form.fields.node.value) var nodeID = form.fields.node.value; if (form.fields.subscriber_jid && form.fields.subscriber_jid.value) var jid = form.fields.subscriber_jid.value; if (form.fields.allow && form.fields.allow.value) var allow = form.fields.allow.value; var type = allow? 'subscribed': 'none'; var set = storage.subscribe(nodeID, jid, type) //if (set.subid != subID) //TODO: support the multi-subscribe feature notifs.send(jid, 'subscription', nodeID, {jid: jid, subscription: type}); } else return makeError(response, errors.feature_not_implemented.n); } else return makeError(response, errors.feature_not_implemented.n); conn.send(response) } function onPresence(stanza) { var from = stanza.getAttribute('to'); var to = stanza.getAttribute('from'); var id = stanza.getAttribute('id'); var response; if (id) response = new Element('presence', {to: to, from: from, id: id}); else response = new Element('presence', {to: to, from: from}); makeError(response, errors.feature_not_implemented.n); } if (process.argv.length >= 3) storage.load(process.argv[2]); else storage.load(); var stdin = process.openStdin(); stdin.setEncoding('utf8'); stdin.addListener('data', storage.debug);