Mercurial > psgxs
view psgxs.js @ 55:fd69d35cf2e6
Move default storage directory; better naming of nodes; fix notification sending.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Mon, 25 Jul 2011 17:35:32 -0700 |
parents | 0d3f18bb1d36 |
children | 99bd1d1ac071 |
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 xmpp = require('xmpp'); var sha1 = require('sha1'); require('./iso8601'); var storage = require('./storage'); var errors = require('./errors'); var makeError = errors.makeError; var fdsq = require('./fdsq'); var toBare = fdsq.toBare; var config = require('./configuration'); var forms = require('./forms'); var conn = new xmpp.Connection(config.host, config.port); var notifs = require('./notifs'); notifs.setConnection(conn); var modules = require('./modules'); var service_configuration = config.service_configuration; var componentJID = config.jid; var componentPassword = config.password; conn.log = function (_, m) { console.log(m); }; 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); }); if (typeof xmpp.StanzaBuilder.cnode != 'function' || typeof xmpp.StanzaBuilder.prototype.cnode != 'function') { xmpp.StanzaBuilder.prototype.cnode = function (stanza) { var parent = this.last_node[this.last_node.length-1]; parent.tags.push(stanza); parent.children.push(stanza); this.last_node.push(stanza); return this; }; } 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 = xmpp.iq({to: to, from: from, type: 'result', id: id}); else response = xmpp.iq({to: to, from: from, type: 'result'}); var send = {}; for (var i in stanza.tags) { var child1 = stanza.tags[i]; if (child1.name == 'pubsub') { for (var j in child1.tags) { var child2 = child1.tags[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.child2 && (module.child2 != child2.name)) continue; if (module.ns && (module.ns != child2.attr.xmlns)) continue; if (module.number && (module.number != j)) continue; send.response = module.func(response, stanza, child2, 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 != child1.name)) continue; if (module.ns && (module.ns != child1.attr.xmlns)) continue; if (module.number && (module.number != k)) continue; send.response = module.func(response, stanza, child1, 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 = xmpp.message({to: to, from: from, id: id}); else response = xmpp.message({to: to, from: from}); var send = false; for (var i in stanza.tags) { var child = stanza.tags[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.attr.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 = xmpp.presence({to: to, from: from, id: id}); else response = xmpp.presence({to: to, from: from}); makeError(response, errors.feature_not_implemented.n); } conn.connect(componentJID, componentPassword, function (status, condition) { if (status == xmpp.Status.CONNECTED) { conn.addHandler(onMessage, null, 'message', null, null, null); conn.addHandler(onIq, null, 'iq', null, null, null); conn.addHandler(onPresence, null, 'presence', null, null, null); 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); } else conn.log(xmpp.LogLevel.DEBUG, 'New connection status: ' + status + (condition? (' ('+condition+')'): '')); });