Permalink
Browse files

Merge branch 'master' of github.com:superfeedr/xmpp-server

  • Loading branch information...
2 parents 6455108 + 1ea744b commit 9765d1146c84526e49f88c510615e1a6f129e084 @julien51 julien51 committed Feb 19, 2012
View
@@ -0,0 +1,2 @@
+.DS_Store
+node_modules
View
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Julien Genestoux and Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
View
@@ -0,0 +1,61 @@
+# xmpp-server
+
+A full XMPP server using node-xmpp, with some modules. Feel free to fork this and configure all the modules you need in server.js
+This server uses Redis as its datastore.
+
+## Installation
+
+<strong>Beware : this project is really early stage... There are a lot of things to fix :) Install it for fun or for help... but probably not for profit just yet!</strong>
+
+1. First, you need **nodejs** installed. Pre-compiled packages exist for Unix (Linux, BSD, Mac OS X) as explained in [these instructions](https://github.com/joyent/node/wiki/Installation). Skip to 2. if you already have a working Node.JS environment.
+
+2. Then, you need **npm** installed. As in step 1, follow [these instructions](http://howtonode.org/introduction-to-npm) or skip to 3.
+
+3. Install **redis** (used to store the data). <code>apt-get install redis-server</code> should work just fine on most Ubuntus and Debians. On MacOS X redis can be installed e.g. with Homebrew: <code>brew install redis</code>
+
+4. Install xmpp-server, finally. With package manager [npm](http://npmjs.org/):
+
+<code>npm install -g xmpp-server </code>
+
+## Running
+
+*TODO : automate this with a script that asks the right questions to the user when starting.*
+
+First, create a config file and place it at <code>/etc/xmpp-server/config.js</code> that includes the following (tls support is optional. You can follow the <a href="http://nodejs.org/docs/v0.4.11/api/tls.html#tLS_">instructions there</a> to create the key and certificate, and then uncomment the <code>tls</code> lines.):
+
+<pre>
+ <code>
+ exports.config = {
+ port: 5222,
+ domain: 'localhost',
+ //tls: {
+ // keyPath: '/etc/xmpp-server/tls/localhost-key.pem',
+ // certPath: '/etc/xmpp-server/tls/localhost-cert.pem'
+ //}
+ }
+ </code>
+</pre>
+
+Then, run the server:
+
+<code>xmpp-server /etc/xmpp-server/config.js </code>
+
+## Trying
+
+There is a server running at [ouvre-boite.com](xmpp://ouvre-boite.com). You can certainly create an account there, but don't leave any valuable belongings as they will be trashed every couple hours :)
+
+## TODO
+
+* <del>In-band registration</del>
+* <del>C2S</del>
+* <del>TLS</del>
+* Digets Auth
+* Roster
+* Presence
+* Pass on global configuration to modules.
+
+
+## Dependencies
+
+* [node-xmpp](http://github.com/astro/node-xmpp)
+* [redis](https://github.com/mranney/node_redis)
View
@@ -0,0 +1,21 @@
+var util = require('util');
+var User = require('../lib/users.js').User;
+var argv = process.argv;
+
+if (argv.length != 4) {
+ util.puts('Usage: node add_user.js <my-jid> <my-password>');
+ process.exit(1);
+}
+
+
+User.register(argv[2], argv[3], {
+ success: function() {
+ console.log(argv[2] + " added.");
+ process.exit(0);
+ },
+ error: function() {
+ console.log(argv[2] + " couldn't ve added. (conflict)");
+ process.exit(1);
+ }
+})
+
View
@@ -0,0 +1,12 @@
+module.exports = {
+ port: 5222,
+ domain: 'localhost',
+
+ // logging
+ logger: false,
+
+ //tls: {
+ // keyPath: '/etc/xmpp-server/tls/localhost-key.pem',
+ // certPath: '/etc/xmpp-server/tls/localhost-cert.pem'
+ //},
+};
View
@@ -0,0 +1,39 @@
+# Design
+
+This documents highlights the design of xmpp-server
+
+Client <- Socket (TCP or else) -> Connection -> Session -> Session Manager -> Router
+
+## Connection
+
+All the low level stuff. [what?]
+
+## Session
+
+Represents a connection + jid (including ressource)
+
+## Session Manager
+
+All the session for a given user
+
+## Router
+
+All the users + Outside world (S2S).
+
+### Flow
+
+ Connection Session Session Manager Router
+
+1. Authentication
+...
+
+2. User sends message to another local user
+...
+
+3. User sends message to non-local user
+...
+
+4.
+...
+
+
View
@@ -0,0 +1,46 @@
+var redis = require("redis"),
+ client = redis.createClient();
+
+client.on("error", function (err) {
+ console.log("Redis connection error to " + client.host + ":" + client.port + " - " + err);
+});
+
+var Message = function(jid, stanza) {
+ this.stanza = stanza;
+ this.jid = jid;
+};
+
+Message.per_jid = 10;
+
+Message.key = function(jid) {
+ return "offline:" + jid.toString();
+};
+
+Message.for = function(jid, cb) {
+ Message.nextFor(jid, cb);
+};
+
+Message.nextFor = function(jid, cb) {
+ client.rpop(Message.key(jid), function(error, stanza) {
+ if(stanza) {
+ cb(new Message(jid, stanza));
+ Message.nextFor(jid, cb);
+ }
+ });
+};
+
+Message.prototype.save = function(callback) {
+ var self = this;
+ client.lpush(Message.key(self.jid), this.stanza, function() {
+ client.ltrim(Message.key(self.jid), 0, Message.per_jid-1, function() {
+ callback(self);
+ });
+ });
+};
+
+exports.Message = Message;
+
+function isEmpty(ob){
+ for(var i in ob){ if(ob.hasOwnProperty(i)){return false;}}
+ return true;
+}
View
@@ -0,0 +1,128 @@
+var util = require('util');
+var EventEmitter = require('events').EventEmitter;
+var redis = require("redis"),
+ client = redis.createClient();
+
+client.on("error", function (err) {
+ console.log("Redis connection error to " + client.host + ":" + client.port + " - " + err);
+});
+
+var Roster = function(owner) {
+ this.owner = owner;
+ this.items = [];
+ return this;
+};
+util.inherits(Roster, EventEmitter);
+
+var RosterItem = function(roster, jid, state, name) {
+ this.roster = roster;
+ this.jid = jid;
+ this.state = state;
+ this.name = name;
+}
+
+Roster.key = function(jid) {
+ return "roster:" + jid.toString();
+};
+
+RosterItem.key = function(owner, jid) {
+ return "rosterItem:" + owner.toString() + ":" + jid.toString();
+}
+
+Roster.find = function(jid, cb) {
+ var roster = new Roster(jid);
+ roster.refresh(cb);
+};
+
+Roster.prototype.refresh = function(cb) {
+ var self = this;
+ client.smembers(Roster.key(self.owner), function(err, obj) {
+ var counts = 0;
+ if(!obj || obj.length == 0) {
+ cb(self);
+ }
+ else {
+ self.items = []; // clear the current items.
+ obj.forEach(function(contact) {
+ RosterItem.find(self, contact, function(item) {
+ counts++;
+ self.items.push(item);
+ if(counts == obj.length) {
+ cb(self);
+ }
+ });
+ });
+ }
+ });
+};
+
+Roster.prototype.eachSubscription = function(types, callback) {
+ var self = this;
+ self.refresh(function() {
+ self.items.forEach(function(item) {
+ if(types.indexOf(item.state) >= 0) {
+ callback(item);
+ }
+ });
+ });
+};
+
+Roster.prototype.itemForJid = function(jid, callback) {
+ var self = this;
+ RosterItem.find(self, jid, function(item) {
+ callback(item);
+ });
+};
+
+Roster.prototype.subscriptions = function(types, callback) {
+ // TODO
+};
+
+Roster.prototype.add = function(jid, callback) {
+ var self = this;
+ self.itemForJid(jid, function(item) {
+ // And now also add the jid to the set
+ client.sadd(Roster.key(self.owner), item.jid, function(err, obj) {
+ callback(item);
+ });
+ });
+};
+
+RosterItem.prototype.save = function(callback) {
+ var self = this;
+ client.hmset(RosterItem.key(self.roster.owner, self.jid), {state: self.state, name: self.name}, function(err, obj) {
+ self.roster.add(self.jid, function() {
+ callback(err, self);
+ });
+ });
+}
+
+RosterItem.prototype.delete = function(callback) {
+ var self = this;
+ client.del(RosterItem.key(self.roster.owner, self.jid), function(err, obj) {
+ client.srem(Roster.key(self.roster.owner), self.jid, function(err, obj) {
+ callback(err, self);
+ });
+ });
+}
+
+RosterItem.find = function(roster, jid, cb) {
+ var self = this;
+ client.hgetall(RosterItem.key(roster.owner, jid), function(err, obj) {
+ if(isEmpty(obj)) {
+ cb(new RosterItem(roster, jid, "none", ""));
+ }
+ else {
+ cb(new RosterItem(roster, jid, obj.state, obj.name));
+ }
+ });
+}
+
+exports.Roster = Roster;
+exports.RosterItem = RosterItem;
+
+
+function isEmpty(ob){
+ for(var i in ob){ if(ob.hasOwnProperty(i)){return false;}}
+ return true;
+}
Oops, something went wrong.

0 comments on commit 9765d11

Please sign in to comment.