cryptpad/www/common/outer/mailbox-handlers.js

202 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

define([
'/common/common-messaging.js',
], function (Messaging) {
var getRandomTimeout = function (ctx) {
var lag = ctx.store.realtime.getLag().lag || 0;
return (Math.max(0, lag) + 300) * 20 * (0.5 + Math.random());
};
var handlers = {};
var removeHandlers = {};
// Store the friend request displayed to avoid duplicates
var friendRequest = {};
handlers['FRIEND_REQUEST'] = function (ctx, box, data, cb) {
// Check if the request is valid (send by the correct user)
if (data.msg.author !== data.msg.content.curvePublic) {
return void cb(true);
}
// Don't show duplicate friend request: if we already have a friend request
// in memory from the same user, dismiss the new one
if (friendRequest[data.msg.author]) { return void cb(true); }
friendRequest[data.msg.author] = true;
// If the user is already in our friend list, automatically accept the request
if (Messaging.getFriend(ctx.store.proxy, data.msg.author) ||
ctx.store.proxy.friends_pending[data.msg.author]) {
Messaging.acceptFriendRequest(ctx.store, data.msg.content, function (obj) {
if (obj && obj.error) {
return void cb();
}
cb(true);
});
return;
}
cb();
};
removeHandlers['FRIEND_REQUEST'] = function (ctx, box, data) {
if (friendRequest[data.content.curvePublic]) {
delete friendRequest[data.content.curvePublic];
}
};
var friendRequestDeclined = {};
handlers['DECLINE_FRIEND_REQUEST'] = function (ctx, box, data, cb) {
setTimeout(function () {
// Our friend request was declined.
if (!ctx.store.proxy.friends_pending[data.msg.author]) { return; }
// Remove the pending message and display the "declined" state in the UI
delete ctx.store.proxy.friends_pending[data.msg.author];
ctx.updateMetadata();
if (friendRequestDeclined[data.msg.author]) { return; }
box.sendMessage({
type: 'FRIEND_REQUEST_DECLINED',
content: {
user: data.msg.author,
name: data.msg.content.displayName
}
}, function () {
if (friendRequestDeclined[data.msg.author]) {
// TODO remove our message because another one was sent first?
}
friendRequestDeclined[data.msg.author] = true;
});
}, getRandomTimeout(ctx));
cb(true);
};
handlers['FRIEND_REQUEST_DECLINED'] = function (ctx, box, data, cb) {
ctx.updateMetadata();
if (friendRequestDeclined[data.msg.content.user]) { return void cb(true); }
friendRequestDeclined[data.msg.content.user] = true;
cb();
};
removeHandlers['FRIEND_REQUEST_DECLINED'] = function (ctx, box, data) {
if (friendRequestDeclined[data.content.user]) {
delete friendRequestDeclined[data.content.user];
}
};
var friendRequestAccepted = {};
handlers['ACCEPT_FRIEND_REQUEST'] = function (ctx, box, data, cb) {
// Our friend request was accepted.
setTimeout(function () {
// Make sure we really sent it
if (!ctx.store.proxy.friends_pending[data.msg.author]) { return; }
// And add the friend
Messaging.addToFriendList({
proxy: ctx.store.proxy,
realtime: ctx.store.realtime,
pinPads: ctx.pinPads
}, data.msg.content, function (err) {
if (err) { console.error(err); }
delete ctx.store.proxy.friends_pending[data.msg.author];
if (ctx.store.messenger) {
ctx.store.messenger.onFriendAdded(data.msg.content);
}
ctx.updateMetadata();
// If you have a profile page open, update it
if (ctx.store.modules['profile']) { ctx.store.modules['profile'].update(); }
if (friendRequestAccepted[data.msg.author]) { return; }
// Display the "accepted" state in the UI
box.sendMessage({
type: 'FRIEND_REQUEST_ACCEPTED',
content: {
user: data.msg.author,
name: data.msg.content.displayName
}
}, function () {
if (friendRequestAccepted[data.msg.author]) {
// TODO remove our message because another one was sent first?
}
friendRequestAccepted[data.msg.author] = true;
});
});
}, getRandomTimeout(ctx));
cb(true);
};
handlers['FRIEND_REQUEST_ACCEPTED'] = function (ctx, box, data, cb) {
ctx.updateMetadata();
if (friendRequestAccepted[data.msg.content.user]) { return void cb(true); }
friendRequestAccepted[data.msg.content.user] = true;
cb();
};
removeHandlers['FRIEND_REQUEST_ACCEPTED'] = function (ctx, box, data) {
if (friendRequestAccepted[data.content.user]) {
delete friendRequestAccepted[data.content.user];
}
};
handlers['UNFRIEND'] = function (ctx, box, data, cb) {
var curve = data.msg.content.curvePublic;
var friend = Messaging.getFriend(ctx.store.proxy, curve);
if (!friend) { return void cb(true); }
delete ctx.store.proxy.friends[curve];
if (ctx.store.messenger) {
ctx.store.messenger.onFriendRemoved(curve, friend.channel);
}
ctx.updateMetadata();
cb(true);
};
handlers['UPDATE_DATA'] = function (ctx, box, data, cb) {
var msg = data.msg;
var curve = msg.author;
var friend = ctx.store.proxy.friends && ctx.store.proxy.friends[curve];
if (!friend || typeof msg.content !== "object") { return void cb(true); }
Object.keys(msg.content).forEach(function (key) {
friend[key] = msg.content[key];
});
ctx.updateMetadata();
cb(true);
};
return {
add: function (ctx, box, data, cb) {
/**
* data = {
msg: {
type: 'STRING',
author: 'curvePublicString',
content: {} (depend on the "type")
},
hash: 'string'
}
*/
if (!data.msg) { return void cb(true); }
var type = data.msg.type;
if (handlers[type]) {
try {
handlers[type](ctx, box, data, cb);
} catch (e) {
console.error(e);
cb();
}
} else {
cb();
}
},
remove: function (ctx, box, data, h) {
// We sometimes try to delete non-existant data (with "delete box.content[h]")
// In this case, we don't have the data in memory so we don't need to call
// any "remove" handler
if (!data) { return; }
var type = data.type;
if (removeHandlers[type]) {
try {
removeHandlers[type](ctx, box, data, h);
} catch (e) {
console.error(e);
}
}
}
};
});