background.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * vim: ts=4:sw=4:expandtab
  3. */
  4. ;(function() {
  5. 'use strict';
  6. window.onInvalidStateError = function(e) {
  7. console.log(e);
  8. };
  9. console.log('background page reloaded');
  10. extension.notification.init();
  11. // Close and reopen existing windows
  12. var open = false;
  13. extension.windows.getAll().forEach(function(appWindow) {
  14. open = true;
  15. appWindow.close();
  16. });
  17. // start a background worker for ecc
  18. textsecure.startWorker('/js/libsignal-protocol-worker.js');
  19. extension.onLaunched(function() {
  20. console.log('extension launched');
  21. storage.onready(function() {
  22. if (Whisper.Registration.everDone()) {
  23. openInbox();
  24. }
  25. if (!Whisper.Registration.isDone()) {
  26. extension.install();
  27. }
  28. });
  29. });
  30. var SERVER_URL = 'https://cable-service-ca.pantelegrafo.cable.im';
  31. var SERVER_PORTS = [443];
  32. var messageReceiver;
  33. window.getSocketStatus = function() {
  34. if (messageReceiver) {
  35. return messageReceiver.getStatus();
  36. } else {
  37. return -1;
  38. }
  39. };
  40. window.events = _.clone(Backbone.Events);
  41. var accountManager;
  42. window.getAccountManager = function() {
  43. if (!accountManager) {
  44. var USERNAME = storage.get('number_id');
  45. var PASSWORD = storage.get('password');
  46. accountManager = new textsecure.AccountManager(
  47. SERVER_URL, SERVER_PORTS, USERNAME, PASSWORD
  48. );
  49. accountManager.addEventListener('registration', function() {
  50. if (!Whisper.Registration.everDone()) {
  51. storage.put('safety-numbers-approval', false);
  52. }
  53. Whisper.Registration.markDone();
  54. console.log("dispatching registration event");
  55. events.trigger('registration_done');
  56. });
  57. }
  58. return accountManager;
  59. };
  60. storage.fetch();
  61. storage.onready(function() {
  62. window.dispatchEvent(new Event('storage_ready'));
  63. setUnreadCount(storage.get("unreadCount", 0));
  64. if (Whisper.Registration.isDone()) {
  65. extension.keepAwake();
  66. init();
  67. }
  68. console.log("listening for registration events");
  69. events.on('registration_done', function() {
  70. console.log("handling registration event");
  71. extension.keepAwake();
  72. init(true);
  73. });
  74. if (open) {
  75. openInbox();
  76. }
  77. WallClockListener.init();
  78. RotateSignedPreKeyListener.init();
  79. ExpiringMessagesListener.init();
  80. });
  81. window.getSyncRequest = function() {
  82. return new textsecure.SyncRequest(textsecure.messaging, messageReceiver);
  83. };
  84. function init(firstRun) {
  85. window.removeEventListener('online', init);
  86. if (!Whisper.Registration.isDone()) { return; }
  87. if (messageReceiver) { messageReceiver.close(); }
  88. var USERNAME = storage.get('number_id');
  89. var PASSWORD = storage.get('password');
  90. var mySignalingKey = storage.get('signaling_key');
  91. // initialize the socket and start listening for messages
  92. messageReceiver = new textsecure.MessageReceiver(
  93. SERVER_URL, SERVER_PORTS, USERNAME, PASSWORD, mySignalingKey
  94. );
  95. messageReceiver.addEventListener('message', onMessageReceived);
  96. messageReceiver.addEventListener('receipt', onDeliveryReceipt);
  97. messageReceiver.addEventListener('contact', onContactReceived);
  98. messageReceiver.addEventListener('group', onGroupReceived);
  99. messageReceiver.addEventListener('sent', onSentMessage);
  100. messageReceiver.addEventListener('read', onReadReceipt);
  101. messageReceiver.addEventListener('error', onError);
  102. window.textsecure.messaging = new textsecure.MessageSender(
  103. SERVER_URL, SERVER_PORTS, USERNAME, PASSWORD
  104. );
  105. if (firstRun === true && textsecure.storage.user.getDeviceId() != '1') {
  106. if (!storage.get('theme-setting') && textsecure.storage.get('userAgent') === 'OWI') {
  107. storage.put('theme-setting', 'ios');
  108. }
  109. var syncRequest = new textsecure.SyncRequest(textsecure.messaging, messageReceiver);
  110. syncRequest.addEventListener('success', function() {
  111. console.log('sync successful');
  112. storage.put('synced_at', Date.now());
  113. window.dispatchEvent(new Event('textsecure:contactsync'));
  114. });
  115. syncRequest.addEventListener('timeout', function() {
  116. console.log('sync timed out');
  117. window.dispatchEvent(new Event('textsecure:contactsync'));
  118. });
  119. }
  120. }
  121. function onContactReceived(ev) {
  122. var contactDetails = ev.contactDetails;
  123. var c = new Whisper.Conversation({
  124. name: contactDetails.name,
  125. id: contactDetails.number,
  126. avatar: contactDetails.avatar,
  127. color: contactDetails.color,
  128. type: 'private',
  129. active_at: Date.now()
  130. });
  131. var error;
  132. if ((error = c.validateNumber())) {
  133. console.log(error);
  134. return;
  135. }
  136. ConversationController.create(c).save();
  137. }
  138. function onGroupReceived(ev) {
  139. var groupDetails = ev.groupDetails;
  140. var attributes = {
  141. id: groupDetails.id,
  142. name: groupDetails.name,
  143. members: groupDetails.members,
  144. avatar: groupDetails.avatar,
  145. type: 'group',
  146. };
  147. if (groupDetails.active) {
  148. attributes.active_at = Date.now();
  149. } else {
  150. attributes.left = true;
  151. }
  152. var conversation = ConversationController.create(attributes);
  153. conversation.save();
  154. }
  155. function onMessageReceived(ev) {
  156. var data = ev.data;
  157. var message = initIncomingMessage(data.source, data.timestamp);
  158. message.handleDataMessage(data.message);
  159. }
  160. function onSentMessage(ev) {
  161. var now = new Date().getTime();
  162. var data = ev.data;
  163. var message = new Whisper.Message({
  164. source : textsecure.storage.user.getNumber(),
  165. sent_at : data.timestamp,
  166. received_at : now,
  167. conversationId : data.destination,
  168. type : 'outgoing',
  169. sent : true,
  170. expirationStartTimestamp: data.expirationStartTimestamp,
  171. });
  172. message.handleDataMessage(data.message);
  173. }
  174. function initIncomingMessage(source, timestamp) {
  175. var now = new Date().getTime();
  176. var message = new Whisper.Message({
  177. source : source,
  178. sent_at : timestamp,
  179. received_at : now,
  180. conversationId : source,
  181. type : 'incoming',
  182. unread : 1
  183. });
  184. return message;
  185. }
  186. function onError(ev) {
  187. var e = ev.error;
  188. console.log(e);
  189. console.log(e.stack);
  190. if (e.name === 'HTTPError' && (e.code == 401 || e.code == 403)) {
  191. Whisper.Registration.remove();
  192. extension.install();
  193. return;
  194. }
  195. if (e.name === 'HTTPError' && e.code == -1) {
  196. // Failed to connect to server
  197. if (navigator.onLine) {
  198. console.log('retrying in 1 minute');
  199. setTimeout(init, 60000);
  200. } else {
  201. console.log('offline');
  202. messageReceiver.close();
  203. window.addEventListener('online', init);
  204. }
  205. return;
  206. }
  207. if (ev.proto) {
  208. if (e.name === 'MessageCounterError') {
  209. // Ignore this message. It is likely a duplicate delivery
  210. // because the server lost our ack the first time.
  211. return;
  212. }
  213. var envelope = ev.proto;
  214. var message = initIncomingMessage(envelope.source, envelope.timestamp.toNumber());
  215. message.saveErrors(e).then(function() {
  216. ConversationController.findOrCreatePrivateById(message.get('conversationId')).then(function(conversation) {
  217. conversation.set({
  218. active_at: Date.now(),
  219. unreadCount: conversation.get('unreadCount') + 1
  220. });
  221. var conversation_timestamp = conversation.get('timestamp');
  222. var message_timestamp = message.get('timestamp');
  223. if (!conversation_timestamp || message_timestamp > conversation_timestamp) {
  224. conversation.set({ timestamp: message.get('sent_at') });
  225. }
  226. conversation.save();
  227. conversation.trigger('newmessage', message);
  228. conversation.notify(message);
  229. });
  230. });
  231. return;
  232. }
  233. throw e;
  234. }
  235. function onReadReceipt(ev) {
  236. var read_at = ev.timestamp;
  237. var timestamp = ev.read.timestamp;
  238. var sender = ev.read.sender;
  239. console.log('read receipt ', sender, timestamp);
  240. Whisper.ReadReceipts.add({
  241. sender : sender,
  242. timestamp : timestamp,
  243. read_at : read_at
  244. });
  245. }
  246. function onDeliveryReceipt(ev) {
  247. var pushMessage = ev.proto;
  248. var timestamp = pushMessage.timestamp.toNumber();
  249. console.log(
  250. 'delivery receipt from',
  251. pushMessage.source + '.' + pushMessage.sourceDevice,
  252. timestamp
  253. );
  254. Whisper.DeliveryReceipts.add({
  255. timestamp: timestamp, source: pushMessage.source
  256. });
  257. }
  258. })();