1
0
mirror of https://github.com/moparisthebest/kaiwa synced 2024-11-22 17:22:22 -05:00
kaiwa/clientapp/helpers/xmppEventHandlers.js

467 lines
14 KiB
JavaScript
Raw Normal View History

2013-09-27 01:52:54 -04:00
/*global me, app, client*/
2013-08-29 23:38:28 -04:00
"use strict";
2013-08-20 13:45:06 -04:00
var _ = require('underscore');
var async = require('async');
2013-09-27 01:52:54 -04:00
var crypto = require('crypto');
2013-12-20 02:04:14 -05:00
var bows = require('bows');
var uuid = require('node-uuid');
var HumanModel = require('human-model');
2013-08-29 23:38:28 -04:00
var Contact = require('../models/contact');
var Resource = require('../models/resource');
var Message = require('../models/message');
2013-10-16 02:00:56 -04:00
var Call = require('../models/call');
2013-08-20 13:45:06 -04:00
2013-12-20 02:04:14 -05:00
var log = bows('Otalk');
var ioLogIn = bows('<< in');
var ioLogOut = bows('>> out');
var discoCapsQueue = async.queue(function (pres, cb) {
var jid = pres.from;
var caps = pres.caps;
2013-12-20 02:04:14 -05:00
log.info('Checking storage for ' + caps.ver);
var contact = me.getContact(jid);
var resource = null;
if (contact) {
resource = contact.resources.get(jid);
}
app.storage.disco.get(caps.ver, function (err, existing) {
if (existing) {
2013-12-20 02:04:14 -05:00
log.info('Already found info for ' + caps.ver);
if (resource) resource.discoInfo = existing;
return cb();
}
2013-12-20 02:04:14 -05:00
log.info('getting info for ' + caps.ver + ' from ' + jid);
client.getDiscoInfo(jid, caps.node + '#' + caps.ver, function (err, result) {
if (err) {
2013-12-20 02:04:14 -05:00
log.error('Couldnt get info for ' + caps.ver);
return cb();
}
if (client.verifyVerString(result.discoInfo, caps.hash, caps.ver)) {
2013-12-20 02:04:14 -05:00
log.info('Saving info for ' + caps.ver);
2015-02-09 09:22:17 -05:00
var data = result.discoInfo;
app.storage.disco.add(caps.ver, data, function () {
if (resource) resource.discoInfo = data;
cb();
});
} else {
2013-12-20 02:04:14 -05:00
log.info('Couldnt verify info for ' + caps.ver + ' from ' + jid);
cb();
}
});
});
});
2013-08-20 13:45:06 -04:00
module.exports = function (client, app) {
client.on('*', function (name, data) {
2013-12-20 02:04:14 -05:00
if (name === 'raw:incoming') {
ioLogIn.debug(data.toString());
} else if (name === 'raw:outgoing') {
ioLogOut.debug(data.toString());
}
2013-08-20 13:45:06 -04:00
});
2013-09-05 19:53:23 -04:00
client.on('credentials:update', function (creds) {
client.config.credentials = creds;
if (creds.clientKey && creds.serverKey) {
delete creds.password;
delete creds.saltedPassword;
} else if (creds.saltedPassword) {
delete creds.password;
}
localStorage.config = JSON.stringify({
jid: client.config.jid.bare,
2013-09-05 19:53:23 -04:00
server: client.config.server,
wsURL: client.config.wsURL,
credentials: creds
});
});
2013-09-17 14:48:03 -04:00
client.on('disconnected', function (err) {
app.state.connected = false;
2013-09-17 14:48:03 -04:00
if (err) {
console.error(err);
}
if (!app.state.hasConnected) {
2013-09-17 14:59:33 -04:00
window.location = '/login';
}
2013-09-05 19:53:23 -04:00
});
client.on('auth:failed', function () {
2013-12-20 13:09:06 -05:00
log.warn('auth failed');
2013-09-05 19:53:23 -04:00
window.location = '/login';
});
2013-09-12 01:02:54 -04:00
client.on('stream:management:resumed', function () {
app.state.connected = true;
2013-09-12 01:02:54 -04:00
});
2013-08-20 13:45:06 -04:00
client.on('session:started', function (jid) {
2015-02-22 17:43:49 -05:00
me.updateJid(jid);
2013-08-20 13:45:06 -04:00
app.state.connected = true;
2014-01-23 14:11:56 -05:00
window.readyForDeviceID = true;
2013-09-05 19:53:23 -04:00
2013-08-20 13:45:06 -04:00
client.getRoster(function (err, resp) {
if (resp.roster && resp.roster.items && resp.roster.items.length) {
2014-01-27 17:55:26 -05:00
app.storage.roster.clear(function () {
me.contacts.reset();
me.rosterVer = resp.roster.ver;
_.each(resp.roster.items, function (item) {
me.setContact(item, true);
});
});
}
2013-08-20 13:45:06 -04:00
var caps = client.updateCaps();
app.storage.disco.add(caps.ver, caps.discoInfo, function () {
client.sendPresence({
status: me.status,
caps: client.disco.caps
});
client.enableCarbons();
2013-08-20 13:45:06 -04:00
});
2013-09-16 19:12:00 -04:00
me.mucs.init();
2013-08-20 13:45:06 -04:00
});
var keepalive;
keepalive = JSON.parse(localStorage.keepalive || '{}');
client.enableKeepAlive(keepalive);
2013-08-20 13:45:06 -04:00
});
client.on('roster:update', function (iq) {
2013-08-29 23:38:28 -04:00
var items = iq.roster.items;
me.rosterVer = iq.roster.ver;
2013-08-29 23:38:28 -04:00
2013-08-20 13:45:06 -04:00
_.each(items, function (item) {
var contact = me.getContact(item.jid);
if (item.subscription === 'remove') {
if (contact) {
2014-01-27 18:02:04 -05:00
me.removeContact(item.jid);
2013-08-20 13:45:06 -04:00
}
return;
}
2013-09-10 03:57:01 -04:00
me.setContact(item, true);
2013-08-20 13:45:06 -04:00
});
});
2013-10-16 13:48:40 -04:00
client.on('subscribe', function (pres) {
me.contactRequests.add({
jid: pres.from.bare
});
});
2013-08-20 13:45:06 -04:00
client.on('available', function (pres) {
var contact = me.getContact(pres.from);
if (contact) {
delete pres.id;
pres.show = pres.show || '';
pres.status = pres.status || '';
pres.priority = pres.priority || 0;
2014-01-05 06:10:57 -05:00
2013-08-20 13:45:06 -04:00
var resource = contact.resources.get(pres.from);
if (resource) {
2013-09-10 03:57:01 -04:00
pres.from = pres.from.full;
2014-01-05 06:10:57 -05:00
// Explicitly set idleSince to null to clear
// the model's value.
if (!pres.idleSince) {
pres.idleSince = null;
}
2013-08-20 13:45:06 -04:00
resource.set(pres);
} else {
resource = new Resource(pres);
resource.id = pres.from.full;
2013-08-20 13:45:06 -04:00
contact.resources.add(resource);
2013-09-13 02:50:27 -04:00
if (!pres.caps) {
resource.fetchDisco();
}
resource.fetchTimezone();
2013-08-20 13:45:06 -04:00
}
2013-12-16 13:06:03 -05:00
var muc = pres.muc || {};
if (muc.codes && muc.codes.indexOf('110') >= 0) {
contact.joined = true;
}
2013-08-20 13:45:06 -04:00
}
});
client.on('unavailable', function (pres) {
var contact = me.getContact(pres.from);
if (contact) {
2013-09-10 03:57:01 -04:00
var resource = contact.resources.get(pres.from.full);
2013-08-20 13:45:06 -04:00
if (resource) {
if (resource.id === contact.lockedResource) {
contact.lockedResource = '';
}
if (contact.resources.length === 1) {
contact.offlineStatus = pres.status;
}
2013-08-20 13:45:06 -04:00
contact.resources.remove(resource);
}
2013-12-16 13:06:03 -05:00
var muc = pres.muc || {};
if (muc.codes && muc.codes.indexOf('110') >= 0) {
contact.joined = false;
}
2013-08-20 13:45:06 -04:00
}
});
client.on('avatar', function (info) {
var contact = me.getContact(info.jid);
2013-09-18 19:24:40 -04:00
if (!contact) {
if (me.isMe(info.jid)) {
contact = me;
} else {
return;
2013-08-20 13:45:06 -04:00
}
}
2013-09-18 19:24:40 -04:00
var id = '';
var type = 'image/png';
if (info.avatars.length > 0) {
id = info.avatars[0].id;
type = info.avatars[0].type || 'image/png';
}
if (contact.setAvatar) {
contact.setAvatar(id, type, info.source);
}
2013-08-20 13:45:06 -04:00
});
client.on('chatState', function (info) {
var contact = me.getContact(info.from);
if (contact) {
var resource = contact.resources.get(info.from.full);
if (resource) {
resource.chatState = info.chatState;
if (info.chatState === 'gone') {
contact.lockedResource = undefined;
2013-09-20 12:52:36 -04:00
} else {
contact.lockedResource = info.from.full;
}
2013-08-20 13:45:06 -04:00
}
} else if (me.isMe(info.from)) {
if (info.chatState === 'active' || info.chatState === 'composing') {
contact = me.getContact(info.to);
if (contact) {
contact.unreadCount = 0;
}
}
2013-08-20 13:45:06 -04:00
}
});
client.on('chat', function (msg) {
2013-12-18 16:31:22 -05:00
msg.mid = msg.id;
delete msg.id;
2013-08-20 13:45:06 -04:00
var contact = me.getContact(msg.from, msg.to);
if (contact && !msg.replace) {
var message = new Message(msg);
2013-08-29 23:38:28 -04:00
2013-09-12 15:03:58 -04:00
if (msg.archived) {
msg.archived.forEach(function (archived) {
if (me.isMe(archived.by)) {
message.archivedId = archived.id;
2013-09-12 15:03:58 -04:00
}
});
}
2013-08-29 23:38:28 -04:00
message.acked = true;
2015-02-15 12:06:39 -05:00
var localTime = new Date(Date.now() + app.timeInterval);
var notify = Math.round((localTime - message.created) / 1000) < 5;
contact.addMessage(message, notify);
if (msg.from.bare == contact.jid.bare) {
contact.lockedResource = msg.from.full;
}
2013-08-20 13:45:06 -04:00
}
});
2013-09-16 19:12:00 -04:00
client.on('groupchat', function (msg) {
2013-12-18 16:31:22 -05:00
msg.mid = msg.id;
delete msg.id;
2013-09-16 19:12:00 -04:00
var contact = me.getContact(msg.from, msg.to);
if (contact && !msg.replace) {
var message = new Message(msg);
message.acked = true;
2015-02-15 12:06:39 -05:00
var localTime = new Date(Date.now() + app.timeInterval);
var notify = Math.round((localTime - message.created) / 1000) < 5;
contact.addMessage(message, notify);
2013-09-16 19:12:00 -04:00
}
});
2015-01-25 09:57:14 -05:00
client.on('muc:subject', function (msg) {
2013-12-20 02:04:14 -05:00
var contact = me.getContact(msg.from, msg.to);
if (contact) {
2015-01-25 09:57:14 -05:00
contact.subject = msg.subject === 'true' ? '' : msg.subject;
2013-12-20 02:04:14 -05:00
}
});
2013-08-20 13:45:06 -04:00
client.on('replace', function (msg) {
2013-12-18 16:31:22 -05:00
msg.mid = msg.id;
delete msg.id;
2013-08-20 13:45:06 -04:00
var contact = me.getContact(msg.from, msg.to);
if (!contact) return;
2013-12-18 16:31:22 -05:00
var original = Message.idLookup(msg.from[msg.type === 'groupchat' ? 'full' : 'bare'], msg.replace);
2013-08-20 13:45:06 -04:00
if (!original) return;
original.correct(msg);
});
client.on('receipt', function (msg) {
var contact = me.getContact(msg.from, msg.to);
if (!contact) return;
var original = Message.idLookup(msg.to[msg.type === 'groupchat' ? 'full' : 'bare'], msg.receipt);
if (!original) return;
original.receiptReceived = true;
});
2013-08-20 13:45:06 -04:00
client.on('carbon:received', function (carbon) {
if (!me.isMe(carbon.from)) return;
var msg = carbon.carbonReceived.forwarded.message;
var delay = carbon.carbonReceived.forwarded.delay;
if (!delay.stamp) {
2015-02-15 12:06:39 -05:00
delay.stamp = new Date(Date.now() + app.timeInterval);
2013-08-20 13:45:06 -04:00
}
if (!msg._extensions.delay) {
msg.delay = delay;
}
client.emit('message', msg);
});
client.on('carbon:sent', function (carbon) {
if (!me.isMe(carbon.from)) return;
var msg = carbon.carbonSent.forwarded.message;
var delay = carbon.carbonSent.forwarded.delay;
if (!delay.stamp) {
2015-02-15 12:06:39 -05:00
delay.stamp = new Date(Date.now() + app.timeInterval);
2013-08-20 13:45:06 -04:00
}
if (!msg._extensions.delay) {
msg.delay = delay;
}
client.emit('message', msg);
});
client.on('disco:caps', function (pres) {
2013-09-11 17:58:39 -04:00
if (pres.caps.hash) {
2013-12-20 02:04:14 -05:00
log.info('Caps from ' + pres.from + ' ver: ' + pres.caps.ver);
discoCapsQueue.push(pres);
}
});
client.on('stanza:acked', function (stanza) {
if (stanza.body) {
var contact = me.getContact(stanza.to, stanza.from);
if (contact) {
2013-12-18 16:31:22 -05:00
var msg = Message.idLookup(me.jid.bare, stanza.id);
if (msg) {
msg.acked = true;
}
}
}
});
2013-10-15 03:02:45 -04:00
client.on('jingle:incoming', function (session) {
var contact = me.getContact(session.peer);
if (!contact) {
contact = new Contact({jid: client.JID(session.peer).bare});
contact.resources.add({id: session.peer});
me.contacts.add(contact);
}
2013-10-16 02:00:56 -04:00
var call = new Call({
2013-10-15 22:16:09 -04:00
contact: contact,
state: 'incoming',
jingleSession: session
});
2013-10-16 02:00:56 -04:00
contact.jingleCall = call;
contact.callState = 'incoming';
2013-10-16 02:00:56 -04:00
me.calls.add(call);
// FIXME: send directed presence if not on roster
2013-10-15 03:02:45 -04:00
});
client.on('jingle:outgoing', function (session) {
var contact = me.getContact(session.peer);
2013-10-16 02:00:56 -04:00
var call = new Call({
2013-10-15 22:16:09 -04:00
contact: contact,
state: 'outgoing',
jingleSession: session
});
2013-10-16 02:00:56 -04:00
contact.jingleCall = call;
me.calls.add(call);
2013-10-15 03:02:45 -04:00
});
client.on('jingle:terminated', function (session) {
var contact = me.getContact(session.peer);
contact.callState = '';
contact.jingleCall = null;
2013-10-16 02:00:56 -04:00
contact.onCall = false;
if (me.calls.length == 1) { // this is the last call
client.jingle.stopLocalMedia();
client.jingle.localStream = null;
}
2013-10-15 03:02:45 -04:00
});
client.on('jingle:accepted', function (session) {
var contact = me.getContact(session.peer);
2013-10-15 04:01:49 -04:00
contact.callState = 'activeCall';
2013-10-16 02:00:56 -04:00
contact.onCall = true;
2013-10-15 03:02:45 -04:00
});
client.on('jingle:localstream:added', function (stream) {
me.stream = stream;
});
client.on('jingle:localstream:removed', function () {
me.stream = null;
});
client.on('jingle:remotestream:added', function (session) {
var contact = me.getContact(session.peer);
if (!contact) {
contact.resources.add({id: session.peer});
me.contacts.add(contact);
}
contact.stream = session.streams[0];
2013-10-15 03:02:45 -04:00
});
client.on('jingle:remotestream:removed', function (session) {
var contact = me.getContact(session.peer);
contact.stream = null;
});
client.on('jingle:ringing', function (session) {
var contact = me.getContact(session.peer);
contact.callState = 'ringing';
});
2013-08-20 13:45:06 -04:00
};