From 799c5b37052aaa0d82718801be42daeecb858527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Hut?= Date: Sun, 25 Oct 2015 16:08:16 +0100 Subject: [PATCH] Update stanza.io (v7) and other dependencies --- Docker/app/config/dev_config.json | 4 +- Docker/app/stanza.io/index-browser.js | 49 ---- Docker/app/stanza.io/muc.js | 265 ------------------ Docker/app/stanza.io/websocket.js | 158 ----------- Docker/app/start.sh | 4 - clientapp/app.js | 13 +- clientapp/helpers/pushNotifications.js | 12 +- clientapp/helpers/xmppEventHandlers.js | 7 +- clientapp/models/contact.js | 16 +- clientapp/models/me.js | 5 +- clientapp/models/message.js | 23 +- clientapp/models/muc.js | 25 +- clientapp/pages/chat.js | 7 +- clientapp/pages/groupchat.js | 5 +- clientapp/templates.js | 2 +- .../templates/includes/contactListItem.jade | 1 - clientapp/views/main.js | 2 +- dev_config.example.json | 12 +- dev_config_ldap.example.json | 26 ++ package.json | 30 +- server.js | 20 +- 21 files changed, 123 insertions(+), 563 deletions(-) delete mode 100644 Docker/app/stanza.io/index-browser.js delete mode 100644 Docker/app/stanza.io/muc.js delete mode 100644 Docker/app/stanza.io/websocket.js create mode 100644 dev_config_ldap.example.json diff --git a/Docker/app/config/dev_config.json b/Docker/app/config/dev_config.json index 4dbd132..f903796 100644 --- a/Docker/app/config/dev_config.json +++ b/Docker/app/config/dev_config.json @@ -2,9 +2,7 @@ "isDev": true, "http": { "baseUrl": "http://localhost:8000", - "port": 8000, - "key": "./fakekeys/privatekey.pem", - "cert": "./fakekeys/certificate.pem" + "port": 8000 }, "session": { "secret": "shhhhhh don't tell anyone ok?" diff --git a/Docker/app/stanza.io/index-browser.js b/Docker/app/stanza.io/index-browser.js deleted file mode 100644 index 4f6401a..0000000 --- a/Docker/app/stanza.io/index-browser.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict'; - -module.exports = function (client) { - // We always need this one first - client.use(require('./disco')); - - client.use(require('./attention')); - client.use(require('./avatar')); - client.use(require('./blocking')); - client.use(require('./bob')); - client.use(require('./bookmarks')); - client.use(require('./carbons')); - client.use(require('./chatstates')); - client.use(require('./command')); - client.use(require('./correction')); - client.use(require('./csi')); - client.use(require('./dataforms')); - client.use(require('./delayed')); - client.use(require('./escaping')); - client.use(require('./extdisco')); - client.use(require('./forwarding')); - client.use(require('./geoloc')); - client.use(require('./hashes')); - client.use(require('./idle')); - client.use(require('./invisible')); - client.use(require('./jidprep')); - //client.use(require('./jingle')); - client.use(require('./json')); - client.use(require('./keepalive')); - client.use(require('./logging')); - client.use(require('./mam')); - client.use(require('./muc')); - client.use(require('./mood')); - client.use(require('./nick')); - client.use(require('./oob')); - client.use(require('./ping')); - client.use(require('./private')); - client.use(require('./psa')); - client.use(require('./pubsub')); - client.use(require('./reach')); - client.use(require('./receipts')); - client.use(require('./register')); - client.use(require('./roster')); - client.use(require('./rtt')); - client.use(require('./shim')); - client.use(require('./time')); - client.use(require('./vcard')); - client.use(require('./version')); -}; diff --git a/Docker/app/stanza.io/muc.js b/Docker/app/stanza.io/muc.js deleted file mode 100644 index 7f62ff7..0000000 --- a/Docker/app/stanza.io/muc.js +++ /dev/null @@ -1,265 +0,0 @@ -'use strict'; - -var stanza = require('jxt'); -var Message = require('./message'); -var Presence = require('./presence'); -var Iq = require('./iq'); -var DataForm = require('./dataforms').DataForm; -var jxtutil = require('jxt-xmpp-types'); - -var NS = 'http://jabber.org/protocol/muc'; -var USER_NS = NS + '#user'; -var ADMIN_NS = NS + '#admin'; -var OWNER_NS = NS + '#owner'; -var UNIQ_NS = NS + '#unique'; - - -var proxy = function (child, field) { - return { - get: function () { - if (this._extensions[child]) { - return this[child][field]; - } - }, - set: function (value) { - this[child][field] = value; - } - }; -}; - -var UserItem = stanza.define({ - name: '_mucUserItem', - namespace: USER_NS, - element: 'item', - fields: { - affiliation: stanza.attribute('affiliation'), - nick: stanza.attribute('nick'), - jid: jxtutil.jidAttribute('jid'), - role: stanza.attribute('role'), - reason: stanza.subText(USER_NS, 'reason') - } -}); - -var UserActor = stanza.define({ - name: '_mucUserActor', - namespace: USER_NS, - element: 'actor', - fields: { - nick: stanza.attribute('nick'), - jid: jxtutil.jidAttribute('jid') - } -}); - -var Destroyed = stanza.define({ - name: 'destroyed', - namespace: USER_NS, - element: 'destroy', - fields: { - jid: jxtutil.jidAttribute('jid'), - reason: stanza.subText(USER_NS, 'reason') - } -}); - -var Invite = stanza.define({ - name: 'invite', - namespace: USER_NS, - element: 'invite', - fields: { - to: jxtutil.jidAttribute('to'), - from: jxtutil.jidAttribute('from'), - reason: stanza.subText(USER_NS, 'reason'), - thread: stanza.subAttribute(USER_NS, 'continue', 'thread'), - 'continue': stanza.boolSub(USER_NS, 'continue') - } -}); - -var Decline = stanza.define({ - name: 'decline', - namespace: USER_NS, - element: 'decline', - fields: { - to: jxtutil.jidAttribute('to'), - from: jxtutil.jidAttribute('from'), - reason: stanza.subText(USER_NS, 'reason') - } -}); - -var AdminItem = stanza.define({ - name: '_mucAdminItem', - namespace: ADMIN_NS, - element: 'item', - fields: { - affiliation: stanza.attribute('affiliation'), - nick: stanza.attribute('nick'), - jid: jxtutil.jidAttribute('jid'), - role: stanza.attribute('role'), - reason: stanza.subText(ADMIN_NS, 'reason') - } -}); - -var AdminActor = stanza.define({ - name: 'actor', - namespace: USER_NS, - element: 'actor', - fields: { - nick: stanza.attribute('nick'), - jid: jxtutil.jidAttribute('jid') - } -}); - -var Destroy = stanza.define({ - name: 'destroy', - namespace: OWNER_NS, - element: 'destroy', - fields: { - jid: jxtutil.jidAttribute('jid'), - password: stanza.subText(OWNER_NS, 'password'), - reason: stanza.subText(OWNER_NS, 'reason') - } -}); - -exports.MUC = stanza.define({ - name: 'muc', - namespace: USER_NS, - element: 'x', - fields: { - affiliation: proxy('_mucUserItem', 'affiliation'), - nick: proxy('_mucUserItem', 'nick'), - jid: proxy('_mucUserItem', 'jid'), - role: proxy('_mucUserItem', 'role'), - actor: proxy('_mucUserItem', '_mucUserActor'), - reason: proxy('_mucUserItem', 'reason'), - password: stanza.subText(USER_NS, 'password'), - codes: { - get: function () { - return stanza.getMultiSubText(this.xml, USER_NS, 'status', function (sub) { - return stanza.getAttribute(sub, 'code'); - }); - }, - set: function (value) { - var self = this; - stanza.setMultiSubText(this.xml, USER_NS, 'status', value, function (val) { - var child = stanza.createElement(USER_NS, 'status', USER_NS); - stanza.setAttribute(child, 'code', val); - self.xml.appendChild(child); - }); - } - } - } -}); - -exports.MUCAdmin = stanza.define({ - name: 'mucAdmin', - namespace: ADMIN_NS, - element: 'query', - fields: { - affiliation: proxy('_mucAdminItem', 'affiliation'), - nick: proxy('_mucAdminItem', 'nick'), - jid: proxy('_mucAdminItem', 'jid'), - role: proxy('_mucAdminItem', 'role'), - actor: proxy('_mucAdminItem', '_mucAdminActor'), - reason: proxy('_mucAdminItem', 'reason') - } -}); - -exports.MUCOwner = stanza.define({ - name: 'mucOwner', - namespace: OWNER_NS, - element: 'query' -}); - -exports.MUCJoin = stanza.define({ - name: 'joinMuc', - namespace: NS, - element: 'x', - fields: { - password: stanza.subText(NS, 'password'), - history: { - get: function () { - var result = {}; - var hist = stanza.find(this.xml, this._NS, 'history'); - - if (!hist.length) { - return {}; - } - hist = hist[0]; - - var maxchars = hist.getAttribute('maxchars') || ''; - var maxstanzas = hist.getAttribute('maxstanas') || ''; - var seconds = hist.getAttribute('seconds') || ''; - var since = hist.getAttribute('since') || ''; - - - if (maxchars) { - result.maxchars = parseInt(maxchars, 10); - } - if (maxstanzas) { - result.maxstanzas = parseInt(maxstanzas, 10); - } - if (seconds) { - result.seconds = parseInt(seconds, 10); - } - if (since) { - result.since = new Date(since); - } - }, - set: function (opts) { - var existing = stanza.find(this.xml, this._NS, 'history'); - if (existing.length) { - for (var i = 0; i < existing.length; i++) { - this.xml.removeChild(existing[i]); - } - } - - var hist = stanza.createElement(this._NS, 'history', this._NS); - this.xml.appendChild(hist); - - if (opts.maxchars) { - hist.setAttribute('maxchars' + opts.maxchars); - } - if (opts.maxstanzas) { - hist.setAttribute('maxstanzas', opts.maxstanzas); - } - if (opts.seconds) { - hist.setAttribute('seconds' + opts.seconds); - } - if (opts.since) { - hist.setAttribute('since', opts.since.toISOString()); - } - } - } - } -}); - -exports.DirectInvite = stanza.define({ - name: 'mucInvite', - namespace: 'jabber:x:conference', - element: 'x', - fields: { - jid: jxtutil.jidAttribute('jid'), - password: stanza.attribute('password'), - reason: stanza.attribute('reason'), - thread: stanza.attribute('thread'), - 'continue': stanza.boolAttribute('continue') - } -}); - - -stanza.add(Iq, 'mucUnique', stanza.subText(UNIQ_NS, 'unique')); - - -stanza.extend(UserItem, UserActor); -stanza.extend(exports.MUC, UserItem); -stanza.extend(exports.MUC, Invite, 'invites'); -stanza.extend(exports.MUC, Decline); -stanza.extend(exports.MUC, Destroyed); -stanza.extend(AdminItem, AdminActor); -stanza.extend(exports.MUCAdmin, AdminItem, 'items'); -stanza.extend(exports.MUCOwner, Destroy); -stanza.extend(exports.MUCOwner, DataForm); -stanza.extend(Presence, exports.MUC); -stanza.extend(Message, exports.MUC); -stanza.extend(Presence, exports.MUCJoin); -stanza.extend(Message, exports.DirectInvite); -stanza.extend(Iq, exports.MUCAdmin); -stanza.extend(Iq, exports.MUCOwner); diff --git a/Docker/app/stanza.io/websocket.js b/Docker/app/stanza.io/websocket.js deleted file mode 100644 index 9a22c87..0000000 --- a/Docker/app/stanza.io/websocket.js +++ /dev/null @@ -1,158 +0,0 @@ -'use strict'; - -var util = require('util'); -var stanza = require('jxt'); -var WildEmitter = require('wildemitter'); -var async = require('async'); -var framing = require('../stanza/framing'); -var StreamError = require('../stanza/streamError'); - -var WS = (require('faye-websocket') && require('faye-websocket').Client) ? - require('faye-websocket').Client : - window.WebSocket; - -var WS_OPEN = 1; - - - -function WSConnection(sm) { - var self = this; - - WildEmitter.call(this); - - self.sm = sm; - self.closing = false; - - self.sendQueue = async.queue(function (data, cb) { - if (self.conn) { - if (typeof data !== 'string') { - data = data.toString(); - } - - data = new Buffer(data, 'utf8').toString(); - - self.emit('raw:outgoing', data); - if (self.conn.readyState === WS_OPEN) { - self.conn.send(data); - } - } - cb(); - }, 1); - - self.on('connected', function () { - self.send(self.startHeader()); - }); - - self.on('raw:incoming', function (data) { - var stanzaObj, err; - - data = data.trim(); - if (data === '') { - return; - } - - if (data.indexOf(" 0 && data.indexOf("") > 0) { - data = data.replace("", "true"); - } - - try { - stanzaObj = stanza.parse(data); - } catch (e) { - err = new StreamError({ - condition: 'invalid-xml' - }); - self.emit('stream:error', err, e); - self.send(err); - return self.disconnect(); - } - - if (stanzaObj._name === 'openStream') { - self.hasStream = true; - self.stream = stanzaObj; - return self.emit('stream:start', stanzaObj.toJSON()); - } - if (stanzaObj._name === 'closeStream') { - self.emit('stream:end'); - return self.disconnect(); - } - - if (!stanzaObj.lang) { - stanzaObj.lang = self.stream ? self.stream.lang : "en"; - } - - self.emit('stream:data', stanzaObj); - }); -} - -util.inherits(WSConnection, WildEmitter); - -WSConnection.prototype.connect = function (opts) { - var self = this; - - self.config = opts; - - self.hasStream = false; - self.closing = false; - - self.conn = new WS(opts.wsURL, 'xmpp'); - self.conn.onerror = function (e) { - e.preventDefault(); - self.emit('disconnected', self); - }; - - self.conn.onclose = function () { - self.emit('disconnected', self); - }; - - self.conn.onopen = function () { - self.sm.started = false; - self.emit('connected', self); - }; - - self.conn.onmessage = function (wsMsg) { - self.emit('raw:incoming', new Buffer(wsMsg.data, 'utf8').toString()); - }; -}; - -WSConnection.prototype.startHeader = function () { - return new framing.Open({ - version: this.config.version || '1.0', - lang: this.config.lang || 'en', - to: this.config.server - }); -}; - -WSConnection.prototype.closeHeader = function () { - return new framing.Close(); -}; - -WSConnection.prototype.disconnect = function () { - if (this.conn && !this.closing) { - this.closing = true; - this.send(this.closeHeader()); - } else { - this.hasStream = false; - this.stream = undefined; - if (this.conn.readyState === WS_OPEN) { - this.conn.close(); - } - this.conn = undefined; - } -}; - -WSConnection.prototype.restart = function () { - var self = this; - self.hasStream = false; - self.send(this.startHeader()); -}; - -WSConnection.prototype.send = function (data) { - this.sendQueue.push(data); -}; - - -module.exports = WSConnection; diff --git a/Docker/app/start.sh b/Docker/app/start.sh index 14d9c62..9258303 100644 --- a/Docker/app/start.sh +++ b/Docker/app/start.sh @@ -29,8 +29,4 @@ echo "Configuring kaiwa..." cd kaiwa -cp /app/stanza.io/websocket.js node_modules/stanza.io/lib/transports -cp /app/stanza.io/index-browser.js node_modules/stanza.io/lib/plugins -cp /app/stanza.io/muc.js node_modules/stanza.io/lib/stanza - node server diff --git a/clientapp/app.js b/clientapp/app.js index fdff2e0..4b1706b 100644 --- a/clientapp/app.js +++ b/clientapp/app.js @@ -25,6 +25,7 @@ module.exports = { launch: function () { var self = window.app = this; + self.JID = StanzaIO.JID; var config = localStorage.config; if (!config) { @@ -41,15 +42,17 @@ module.exports = { var profile = {}; async.series([ function (cb) { + app.composing = {}; + app.timeInterval = 0; + app.mucInfos = []; app.notifications = new Notify(); app.soundManager = new SoundEffectManager(); app.desktop = new Desktop(); app.cache = new AppCache(); app.storage = new Storage(); - app.storage.open(cb); - app.composing = {}; - app.timeInterval = 0; - app.mucInfos = []; + app.storage.open(function() { + cb(); + }); }, function (cb) { app.storage.profiles.get(app.config.jid, function (err, res) { @@ -109,7 +112,7 @@ module.exports = { function start() { // start our router and show the appropriate page app.history.start({pushState: true, root: '/'}); - if (app.history.fragment == '' && SERVER_CONFIG.startup) + if (app.history.fragment === '' && SERVER_CONFIG.startup) app.navigate(SERVER_CONFIG.startup); cb(); } diff --git a/clientapp/helpers/pushNotifications.js b/clientapp/helpers/pushNotifications.js index 21f4d63..8b0b4f3 100644 --- a/clientapp/helpers/pushNotifications.js +++ b/clientapp/helpers/pushNotifications.js @@ -1,10 +1,12 @@ "use strict"; var jxt = require('jxt'); -var stanzaio = require('stanza.io'); +var JXT = jxt.createRegistry(); +JXT.use(require('jxt-xmpp-types')); +JXT.use(require('jxt-xmpp')); -jxt.extend(stanzaio.Message, jxt.define({ +jxt.extend(JXT.getMessage(), jxt.define({ name: 'pushNotification', namespace: 'urn:xmpp:push:0', element: 'push', @@ -13,7 +15,7 @@ jxt.extend(stanzaio.Message, jxt.define({ } })); -jxt.extend(stanzaio.Iq, jxt.define({ +jxt.extend(JXT.getIQ(), jxt.define({ name: 'registerPush', namespace: 'urn:xmpp:push:0', element: 'register', @@ -22,7 +24,7 @@ jxt.extend(stanzaio.Iq, jxt.define({ } })); -jxt.extend(stanzaio.Iq, jxt.define({ +jxt.extend(JXT.getIQ(), jxt.define({ name: 'unregisterPush', namespace: 'urn:xmpp:push:0', element: 'unregister', @@ -32,7 +34,7 @@ jxt.extend(stanzaio.Iq, jxt.define({ })); -jxt.extend(stanzaio.Iq, jxt.define({ +jxt.extend(JXT.getIQ(), jxt.define({ name: 'otalkRegister', namespace: 'http://otalk.im/protocol/push', element: 'register', diff --git a/clientapp/helpers/xmppEventHandlers.js b/clientapp/helpers/xmppEventHandlers.js index 20e464b..954a7f7 100644 --- a/clientapp/helpers/xmppEventHandlers.js +++ b/clientapp/helpers/xmppEventHandlers.js @@ -86,11 +86,8 @@ module.exports = function (client, app) { }); }); - client.on('disconnected', function (err) { + client.on('disconnected', function () { app.state.connected = false; - if (err) { - console.error(err); - } if (!app.state.hasConnected) { window.location = '/login'; } @@ -372,7 +369,7 @@ module.exports = function (client, app) { client.on('jingle:incoming', function (session) { var contact = me.getContact(session.peer); if (!contact) { - contact = new Contact({jid: client.JID(session.peer).bare}); + contact = new Contact({jid: new app.JID(session.peer).bare}); contact.resources.add({id: session.peer}); me.contacts.add(contact); } diff --git a/clientapp/models/contact.js b/clientapp/models/contact.js index 5509d8d..45953fa 100644 --- a/clientapp/models/contact.js +++ b/clientapp/models/contact.js @@ -339,21 +339,23 @@ module.exports = HumanModel.define({ } } - client.getHistory(filter, function (err, res) { + client.searchHistory(filter, function (err, res) { if (err) return; self.lastHistoryFetch = new Date(Date.now() + app.timeInterval); - var results = res.mamQuery.results || []; - if (!!onlyLastMessages && !allInterval) results.reverse(); + var results = res.mamResult.items || []; + if (filter.rsm.before) { + results.reverse(); + } results.forEach(function (result) { - var msg = result.mam.forwarded.message; + var msg = result.forwarded.message; msg.mid = msg.id; delete msg.id; if (!msg.delay) { - msg.delay = result.mam.forwarded.delay; + msg.delay = result.forwarded.delay; } if (msg.replace) { @@ -365,14 +367,14 @@ module.exports = HumanModel.define({ } var message = new Message(msg); - message.archivedId = result.mam.id; + message.archivedId = result.id; message.acked = true; self.addMessage(message, false); }); if (allInterval) { - if (results.length == 40) { + if (results.length === filter.rsm.max) { self.fetchHistory(true, true); } else { self.trigger('refresh'); diff --git a/clientapp/models/me.js b/clientapp/models/me.js index da68a5b..b69ce89 100644 --- a/clientapp/models/me.js +++ b/clientapp/models/me.js @@ -88,6 +88,7 @@ module.exports = HumanModel.define({ var prev = this.getContact(this._activeContact); if (prev) { prev.activeContact = false; + this._activeContact = ''; } var curr = this.getContact(jid); if (curr) { @@ -143,9 +144,9 @@ module.exports = HumanModel.define({ getContact: function (jid, alt) { if (typeof jid === 'string') { if (SERVER_CONFIG.domain && jid.indexOf('@') == -1) jid += '@' + SERVER_CONFIG.domain; - jid = new client.JID(jid); + jid = new app.JID(jid); } - if (typeof alt === 'string') alt = new client.JID(alt); + if (typeof alt === 'string') alt = new app.JID(alt); if (this.isMe(jid)) { jid = alt || jid; diff --git a/clientapp/models/message.js b/clientapp/models/message.js index 145d0db..0794f3c 100644 --- a/clientapp/models/message.js +++ b/clientapp/models/message.js @@ -109,16 +109,19 @@ var Message = module.exports = HumanModel.define({ deps: ['body', 'meAction', 'mentions'], fn: function () { var body = this.body; - if (this.meAction) { - body = body.substr(4); + if (body) { + if (this.meAction) { + body = body.substr(4); + } + body = htmlify.toHTML(body); + for (var i = 0; i < this.mentions.length; i++) { + var existing = htmlify.toHTML(this.mentions[i]); + var parts = body.split(existing); + body = parts.join('' + existing + ''); + } + return body; } - body = htmlify.toHTML(body); - for (var i = 0; i < this.mentions.length; i++) { - var existing = htmlify.toHTML(this.mentions[i]); - var parts = body.split(existing); - body = parts.join('' + existing + ''); - } - return body; + this.body = ''; } }, partialTemplateHtml: { @@ -158,7 +161,7 @@ var Message = module.exports = HumanModel.define({ meAction: { deps: ['body'], fn: function () { - return this.body.indexOf('/me') === 0; + return this.body && this.body.indexOf('/me') === 0; } }, urls: { diff --git a/clientapp/models/muc.js b/clientapp/models/muc.js index f63cc74..883b723 100644 --- a/clientapp/models/muc.js +++ b/clientapp/models/muc.js @@ -55,7 +55,7 @@ module.exports = HumanModel.define({ if (this.unreadCount < 100) return this.unreadCount.toString(); else - return '99+' + return '99+'; } return ''; } @@ -84,7 +84,7 @@ module.exports = HumanModel.define({ if (xmppContact) { name = xmppContact.displayName; } - return name != '' ? name : nickname; + return name !== '' ? name : nickname; }, getNickname: function (jid) { var nickname = jid.split('/')[1]; @@ -148,7 +148,7 @@ module.exports = HumanModel.define({ this.lastSentMessage = message; } - var existing = Message.idLookup(message.from['full'], message.mid); + var existing = Message.idLookup(message.from.full, message.mid); if (existing) { existing.set(message); existing.save(); @@ -163,6 +163,7 @@ module.exports = HumanModel.define({ } }, join: function (manual) { + var self = this; if (!this.nick) { this.nick = me.jid.local; } @@ -202,7 +203,6 @@ module.exports = HumanModel.define({ }); if (SERVER_CONFIG.domain && SERVER_CONFIG.admin) { - var self = this; client.setRoomAffiliation(this.jid, SERVER_CONFIG.admin + '@' + SERVER_CONFIG.domain, 'owner', 'administration', function(err, resp) { if (err) return; client.setRoomAffiliation(self.jid, me.jid, 'none', 'administration'); @@ -210,7 +210,6 @@ module.exports = HumanModel.define({ } } - var self = this; // After a reconnection client.on('muc:join', function (pres) { if (self.messages.length) { @@ -243,19 +242,21 @@ module.exports = HumanModel.define({ } } - client.getHistory(filter, function (err, res) { + client.searchHistory(filter, function (err, res) { if (err) return; - var results = res.mamQuery.results || []; - + var results = res.mamResult.items || []; + if (filter.rsm.before) { + results.reverse(); + } results.forEach(function (result) { - var msg = result.mam.forwarded.message; + var msg = result.forwarded.message; msg.mid = msg.id; delete msg.id; if (!msg.delay) { - msg.delay = result.mam.forwarded.delay; + msg.delay = result.forwarded.delay; } if (msg.replace) { @@ -267,7 +268,7 @@ module.exports = HumanModel.define({ } var message = new Message(msg); - message.archivedId = result.mam.id; + message.archivedId = result.id; message.acked = true; self.addMessage(message, false); @@ -275,7 +276,7 @@ module.exports = HumanModel.define({ if (allInterval) { self.trigger('refresh'); - if (results.length == 40) + if (results.length === filter.rsm.max) self.fetchHistory(true); } }); diff --git a/clientapp/pages/chat.js b/clientapp/pages/chat.js index ebe69b2..8a05286 100644 --- a/clientapp/pages/chat.js +++ b/clientapp/pages/chat.js @@ -15,6 +15,7 @@ var attachMediaStream = require('attachmediastream'); module.exports = BasePage.extend({ template: templates.pages.chat, initialize: function (spec) { + var self = this; this.editMode = false; this.listenTo(this, 'pageloaded', this.handlePageLoaded); @@ -187,7 +188,7 @@ module.exports = BasePage.extend({ message = { id: client.nextId(), - to: client.JID(this.model.lockedResource || this.model.jid), + to: new app.JID(this.model.lockedResource || this.model.jid), type: 'chat', body: val, requestReceipt: true, @@ -314,12 +315,12 @@ module.exports = BasePage.extend({ condition: 'decline' }); } else { - client.sendPresence({to: client.JID(self.model.jingleCall.jingleSession.peer) }); + client.sendPresence({to: new app.JID(self.model.jingleCall.jingleSession.peer) }); self.model.jingleCall.jingleSession.accept(); } }); } else { - client.sendPresence({to: client.JID(this.model.jingleCall.jingleSession.peer) }); + client.sendPresence({to: new app.JID(this.model.jingleCall.jingleSession.peer) }); this.model.jingleCall.jingleSession.accept(); } } diff --git a/clientapp/pages/groupchat.js b/clientapp/pages/groupchat.js index b2f82b3..f3c3d30 100644 --- a/clientapp/pages/groupchat.js +++ b/clientapp/pages/groupchat.js @@ -15,6 +15,7 @@ var tempSubject = ''; module.exports = BasePage.extend({ template: templates.pages.groupchat, initialize: function (spec) { + var self = this; this.editMode = false; this.listenTo(this, 'pageloaded', this.handlePageLoaded); @@ -301,7 +302,7 @@ module.exports = BasePage.extend({ var id = client.sendMessage(message); message.mid = id; - message.from = client.JID(this.model.jid.bare + '/' + this.model.nick); + message.from = new app.JID(this.model.jid.bare + '/' + this.model.nick); if (this.editMode) { this.model.lastSentMessage.correct(message); @@ -322,7 +323,7 @@ module.exports = BasePage.extend({ }, blurStatusChange: function (e) { var subject = e.target.textContent; - if (subject == '') + if (subject === '') subject = true; client.setSubject(this.model.jid, subject); e.target.textContent = tempSubject; diff --git a/clientapp/templates.js b/clientapp/templates.js index a2d758d..11a68e8 100644 --- a/clientapp/templates.js +++ b/clientapp/templates.js @@ -113,7 +113,7 @@ exports.includes.call = function anonymous(locals) { exports.includes.contactListItem = function anonymous(locals) { var buf = []; with (locals || {}) { - buf.push('
  • ' + jade.escape(null == (jade.interp = contact.displayName) ? "" : jade.interp) + '' + jade.escape(null == (jade.interp = contact.idleSince) ? "" : jade.interp) + '
    ' + jade.escape(null == (jade.interp = contact.unreadCount) ? "" : jade.interp) + "
  • "); + buf.push('
  • ' + jade.escape(null == (jade.interp = contact.displayName) ? "" : jade.interp) + '
    ' + jade.escape(null == (jade.interp = contact.unreadCount) ? "" : jade.interp) + "
  • "); } return buf.join(""); }; diff --git a/clientapp/templates/includes/contactListItem.jade b/clientapp/templates/includes/contactListItem.jade index 3059aac..d317907 100644 --- a/clientapp/templates/includes/contactListItem.jade +++ b/clientapp/templates/includes/contactListItem.jade @@ -5,5 +5,4 @@ li.contact.joined .user img.avatar span.name=contact.displayName - span.idleTime=contact.idleSince .unread=contact.unreadCount diff --git a/clientapp/views/main.js b/clientapp/views/main.js index df69aa3..1a072ea 100644 --- a/clientapp/views/main.js +++ b/clientapp/views/main.js @@ -132,7 +132,7 @@ module.exports = HumanView.extend({ me.mucs.add({ id: mucjid, name: mucjid, - jid: new client.JID(mucjid), + jid: new app.JID(mucjid), nick: me.nick, autoJoin: true }); diff --git a/dev_config.example.json b/dev_config.example.json index 0905c06..31e3c6a 100644 --- a/dev_config.example.json +++ b/dev_config.example.json @@ -2,9 +2,7 @@ "isDev": true, "http": { "baseUrl": "http://localhost:8000", - "port": 8000, - "key": "./fakekeys/privatekey.pem", - "cert": "./fakekeys/certificate.pem" + "port": 8000 }, "session": { "secret": "shhhhhh don't tell anyone ok?" @@ -16,13 +14,5 @@ "muc": "chat.example.com", "startup": "groupchat/room%40chat.example.com", "admin": "admin" - }, - "ldap": { - "address": "127.0.0.1", - "user": "cn=admin,dc=example.com", - "password": "password", - "base": "ou=users,dc=example.com", - "filter": "objectClass=person", - "group": "cn=mygroup,ou=groups,dc=example.com" } } diff --git a/dev_config_ldap.example.json b/dev_config_ldap.example.json new file mode 100644 index 0000000..31d6525 --- /dev/null +++ b/dev_config_ldap.example.json @@ -0,0 +1,26 @@ +{ + "isDev": true, + "http": { + "baseUrl": "http://localhost:8000", + "port": 8000 + }, + "session": { + "secret": "shhhhhh don't tell anyone ok?" + }, + "server": { + "name": "Kaiwa", + "domain": "example.com", + "wss": "wss://example.com:5281/xmpp-websocket/", + "muc": "chat.example.com", + "startup": "groupchat/room%40chat.example.com", + "admin": "admin" + }, + "ldap": { + "address": "127.0.0.1", + "user": "cn=admin,dc=example.com", + "password": "password", + "base": "ou=users,dc=example.com", + "filter": "objectClass=person", + "group": "cn=mygroup,ou=groups,dc=example.com" + } +} diff --git a/package.json b/package.json index b41306b..4f3f303 100644 --- a/package.json +++ b/package.json @@ -7,38 +7,41 @@ }, "dependencies": { "andlog": "0.0.4", - "async": "^0.9.0", + "async": "^1.4.0", "attachmediastream": "1.0.1", "backbone": "1.0.0", "bluebird": "^2.3.2", "body-parser": "1.12.0", "bows": "0.3.0", - "browserify": "4.x", "compression": "1.2.2", "crypto-browserify": "", - "express": "4.10.6", + "express": "4.13.3", "getconfig": "0.0.5", "getusermedia": "0.2.1", "helmet": "0.1.0", "human-model": "2.6.0", "human-view": "1.8.0", "jade": "1.8.2", - "jxt": "^2.7.0", + "jxt": "^3.0.4", + "jxt-xmpp": "^1.2.3", + "jxt-xmpp-types": "^3.0.0", "ldapjs": "0.7.1", - "moonboots-express": "2.x", + "moonboots-express": "^3.0", "node-uuid": "^1.4.1", "notify.js": "0.0.3", "semi-static": "0.0.4", "serve-static": "1.7.1", "sound-effect-manager": "1.0.0", - "stanza.io": "6.10.2", + "stanza.io": "7.3.4", "staydown": "1.0.3", "templatizer": "0.1.2", "underscore": "1.6.0", - "wildemitter": "^1.0.1" + "wildemitter": "^1.0.1", + "xmpp-constants": "^2.2.2" }, "devDependencies": { - "precommit-hook": "^1.0.2" + "browserify": "^11.0.1", + "precommit-hook": "^3.0.0" }, "license": "MIT", "main": "server.js", @@ -46,5 +49,14 @@ "repository": { "type": "git", "url": "git@github.com:digicoop/kaiwa.git" - } + }, + "scripts": { + "lint": "jshint .", + "validate": "npm ls" + }, + "pre-commit": [ + "lint", + "validate", + "test" + ] } diff --git a/server.js b/server.js index 72d24f4..a739205 100644 --- a/server.js +++ b/server.js @@ -1,8 +1,8 @@ var fs = require('fs'); var https = require('https'); +var Moonboots = require('moonboots-express'); var express = require('express'); var helmet = require('helmet'); -var Moonboots = require('moonboots-express'); var config = require('getconfig'); var templatizer = require('templatizer'); var async = require('async'); @@ -10,10 +10,10 @@ var LDAP = require('ldapjs'); String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); -} +}; var app = express(); -var bodyParser = require('body-parser') +var bodyParser = require('body-parser'); var compression = require('compression'); var serveStatic = require('serve-static'); @@ -42,7 +42,7 @@ app.get('/logout', function (req, res) { app.get('/config.js', function (req, res) { res.type('application/javascript'); - res.send("var SERVER_CONFIG = " + JSON.stringify(config.server) + ";"); + res.send("window.SERVER_CONFIG = " + JSON.stringify(config.server) + ";"); }); app.get('/sounds/*', function (req, res) { @@ -66,7 +66,7 @@ function connectLDAP(req, cb) { function closeCb(client) { client.unbind(); console.log("LDAP: Disconnected"); - }; + } client.bind(ldapDN, ldapPW, function(err) { if (err) { @@ -107,11 +107,11 @@ app.post('/ldap/user/:id', function(req, res) { if (err === false) { var changes = []; - if (req.body.cn != undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {cn: req.body.cn}})); - if (req.body.sn != undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {sn: req.body.sn}})); - if (req.body.givenName != undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {givenName: req.body.givenName}})); - if (req.body.displayName != undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {displayName: req.body.displayName}})); - if (req.body.mail != undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {mail: req.body.mail}})); + if (req.body.cn !== undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {cn: req.body.cn}})); + if (req.body.sn !== undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {sn: req.body.sn}})); + if (req.body.givenName !== undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {givenName: req.body.givenName}})); + if (req.body.displayName !== undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {displayName: req.body.displayName}})); + if (req.body.mail !== undefined) changes.push(new LDAP.Change({ operation: 'replace', modification: {mail: req.body.mail}})); client.modify(dn, changes, function (err) { if (err) {