| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  | /* global window, getString, libsignal, textsecure */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* eslint-disable more/no-then */ | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  | // eslint-disable-next-line func-names
 | 
					
						
							|  |  |  | (function() { | 
					
						
							|  |  |  |   /** ******************* | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |    *** Group Storage *** | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |    ******************** */ | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |   window.textsecure = window.textsecure || {}; | 
					
						
							|  |  |  |   window.textsecure.storage = window.textsecure.storage || {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // create a random group id that we haven't seen before.
 | 
					
						
							|  |  |  |   function generateNewGroupId() { | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     const groupId = getString(libsignal.crypto.getRandomBytes(16)); | 
					
						
							|  |  |  |     return textsecure.storage.protocol.getGroup(groupId).then(group => { | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |       if (group === undefined) { | 
					
						
							|  |  |  |         return groupId; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |       window.log.warn('group id collision'); // probably a bad sign.
 | 
					
						
							|  |  |  |       return generateNewGroupId(); | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   window.textsecure.storage.groups = { | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     createNewGroup(numbers, groupId) { | 
					
						
							|  |  |  |       return new Promise(resolve => { | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |         if (groupId !== undefined) { | 
					
						
							|  |  |  |           resolve( | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |             textsecure.storage.protocol.getGroup(groupId).then(group => { | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |               if (group !== undefined) { | 
					
						
							|  |  |  |                 throw new Error('Tried to recreate group'); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           resolve( | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |             generateNewGroupId().then(newGroupId => { | 
					
						
							|  |  |  |               // eslint-disable-next-line no-param-reassign
 | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |               groupId = newGroupId; | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |       }).then(() => { | 
					
						
							|  |  |  |         const me = textsecure.storage.user.getNumber(); | 
					
						
							|  |  |  |         let haveMe = false; | 
					
						
							|  |  |  |         const finalNumbers = []; | 
					
						
							|  |  |  |         // eslint-disable-next-line no-restricted-syntax, guard-for-in
 | 
					
						
							|  |  |  |         for (const i in numbers) { | 
					
						
							|  |  |  |           const number = numbers[i]; | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |           if (!textsecure.utils.isNumberSane(number)) | 
					
						
							|  |  |  |             throw new Error('Invalid number in group'); | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |           if (number === me) haveMe = true; | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |           if (finalNumbers.indexOf(number) < 0) finalNumbers.push(number); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-10-28 20:30:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |         if (!haveMe) finalNumbers.push(me); | 
					
						
							| 
									
										
										
										
											2014-10-28 20:30:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |         const groupObject = { | 
					
						
							|  |  |  |           numbers: finalNumbers, | 
					
						
							|  |  |  |           numberRegistrationIds: {}, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         // eslint-disable-next-line no-restricted-syntax, guard-for-in
 | 
					
						
							|  |  |  |         for (const i in finalNumbers) { | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |           groupObject.numberRegistrationIds[finalNumbers[i]] = {}; | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-05-06 13:11:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |         return textsecure.storage.protocol | 
					
						
							|  |  |  |           .putGroup(groupId, groupObject) | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |           .then(() => ({ id: groupId, numbers: finalNumbers })); | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2014-10-28 20:30:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     getNumbers(groupId) { | 
					
						
							|  |  |  |       return textsecure.storage.protocol.getGroup(groupId).then(group => { | 
					
						
							|  |  |  |         if (group === undefined) return undefined; | 
					
						
							| 
									
										
										
										
											2014-10-28 20:30:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |         return group.numbers; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     removeNumber(groupId, number) { | 
					
						
							|  |  |  |       return textsecure.storage.protocol.getGroup(groupId).then(group => { | 
					
						
							|  |  |  |         if (group === undefined) return undefined; | 
					
						
							| 
									
										
										
										
											2014-10-28 20:30:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |         const me = textsecure.storage.user.getNumber(); | 
					
						
							|  |  |  |         if (number === me) | 
					
						
							|  |  |  |           throw new Error( | 
					
						
							|  |  |  |             'Cannot remove ourselves from a group, leave the group instead' | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const i = group.numbers.indexOf(number); | 
					
						
							|  |  |  |         if (i > -1) { | 
					
						
							|  |  |  |           group.numbers.splice(i, 1); | 
					
						
							|  |  |  |           // eslint-disable-next-line no-param-reassign
 | 
					
						
							|  |  |  |           delete group.numberRegistrationIds[number]; | 
					
						
							|  |  |  |           return textsecure.storage.protocol | 
					
						
							|  |  |  |             .putGroup(groupId, group) | 
					
						
							|  |  |  |             .then(() => group.numbers); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return group.numbers; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     addNumbers(groupId, numbers) { | 
					
						
							|  |  |  |       return textsecure.storage.protocol.getGroup(groupId).then(group => { | 
					
						
							|  |  |  |         if (group === undefined) return undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // eslint-disable-next-line no-restricted-syntax, guard-for-in
 | 
					
						
							|  |  |  |         for (const i in numbers) { | 
					
						
							|  |  |  |           const number = numbers[i]; | 
					
						
							|  |  |  |           if (!textsecure.utils.isNumberSane(number)) | 
					
						
							|  |  |  |             throw new Error('Invalid number in set to add to group'); | 
					
						
							|  |  |  |           if (group.numbers.indexOf(number) < 0) { | 
					
						
							|  |  |  |             group.numbers.push(number); | 
					
						
							|  |  |  |             // eslint-disable-next-line no-param-reassign
 | 
					
						
							|  |  |  |             group.numberRegistrationIds[number] = {}; | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-10-28 20:30:35 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |         return textsecure.storage.protocol | 
					
						
							|  |  |  |           .putGroup(groupId, group) | 
					
						
							|  |  |  |           .then(() => group.numbers); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2015-06-22 17:55:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     deleteGroup(groupId) { | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |       return textsecure.storage.protocol.removeGroup(groupId); | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2015-06-22 17:55:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     getGroup(groupId) { | 
					
						
							|  |  |  |       return textsecure.storage.protocol.getGroup(groupId).then(group => { | 
					
						
							|  |  |  |         if (group === undefined) return undefined; | 
					
						
							| 
									
										
										
										
											2015-06-22 17:55:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |         return { id: groupId, numbers: group.numbers }; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 14:51:20 -07:00
										 |  |  |     updateNumbers(groupId, numbers) { | 
					
						
							|  |  |  |       return textsecure.storage.protocol.getGroup(groupId).then(group => { | 
					
						
							|  |  |  |         if (group === undefined) | 
					
						
							|  |  |  |           throw new Error('Tried to update numbers for unknown group'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ( | 
					
						
							|  |  |  |           numbers.filter(textsecure.utils.isNumberSane).length < numbers.length | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |           throw new Error('Invalid number in new group members'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const added = numbers.filter( | 
					
						
							|  |  |  |           number => group.numbers.indexOf(number) < 0 | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return textsecure.storage.groups.addNumbers(groupId, added); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-05-02 09:51:22 -07:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2014-10-28 20:30:35 -07:00
										 |  |  | })(); |