You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			159 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			159 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
| /* global window, getString, libsignal, textsecure */
 | |
| 
 | |
| /* eslint-disable more/no-then */
 | |
| 
 | |
| // eslint-disable-next-line func-names
 | |
| (function() {
 | |
|   /** *******************
 | |
|    *** Group Storage ***
 | |
|    ******************** */
 | |
|   window.textsecure = window.textsecure || {};
 | |
|   window.textsecure.storage = window.textsecure.storage || {};
 | |
| 
 | |
|   // create a random group id that we haven't seen before.
 | |
|   function generateNewGroupId() {
 | |
|     const groupId = getString(libsignal.crypto.getRandomBytes(16));
 | |
|     return textsecure.storage.protocol.getGroup(groupId).then(group => {
 | |
|       if (group === undefined) {
 | |
|         return groupId;
 | |
|       }
 | |
|       window.log.warn('group id collision'); // probably a bad sign.
 | |
|       return generateNewGroupId();
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   window.textsecure.storage.groups = {
 | |
|     createNewGroup(numbers, groupId) {
 | |
|       return new Promise(resolve => {
 | |
|         if (groupId !== undefined) {
 | |
|           resolve(
 | |
|             textsecure.storage.protocol.getGroup(groupId).then(group => {
 | |
|               if (group !== undefined) {
 | |
|                 throw new Error('Tried to recreate group');
 | |
|               }
 | |
|             })
 | |
|           );
 | |
|         } else {
 | |
|           resolve(
 | |
|             generateNewGroupId().then(newGroupId => {
 | |
|               // eslint-disable-next-line no-param-reassign
 | |
|               groupId = newGroupId;
 | |
|             })
 | |
|           );
 | |
|         }
 | |
|       }).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];
 | |
|           if (!textsecure.utils.isNumberSane(number))
 | |
|             throw new Error('Invalid number in group');
 | |
|           if (number === me) haveMe = true;
 | |
|           if (finalNumbers.indexOf(number) < 0) finalNumbers.push(number);
 | |
|         }
 | |
| 
 | |
|         if (!haveMe) finalNumbers.push(me);
 | |
| 
 | |
|         const groupObject = {
 | |
|           numbers: finalNumbers,
 | |
|           numberRegistrationIds: {},
 | |
|         };
 | |
|         // eslint-disable-next-line no-restricted-syntax, guard-for-in
 | |
|         for (const i in finalNumbers) {
 | |
|           groupObject.numberRegistrationIds[finalNumbers[i]] = {};
 | |
|         }
 | |
| 
 | |
|         return textsecure.storage.protocol
 | |
|           .putGroup(groupId, groupObject)
 | |
|           .then(() => ({ id: groupId, numbers: finalNumbers }));
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     getNumbers(groupId) {
 | |
|       return textsecure.storage.protocol.getGroup(groupId).then(group => {
 | |
|         if (group === undefined) return undefined;
 | |
| 
 | |
|         return group.numbers;
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     removeNumber(groupId, number) {
 | |
|       return textsecure.storage.protocol.getGroup(groupId).then(group => {
 | |
|         if (group === undefined) return undefined;
 | |
| 
 | |
|         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;
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     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] = {};
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         return textsecure.storage.protocol
 | |
|           .putGroup(groupId, group)
 | |
|           .then(() => group.numbers);
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     deleteGroup(groupId) {
 | |
|       return textsecure.storage.protocol.removeGroup(groupId);
 | |
|     },
 | |
| 
 | |
|     getGroup(groupId) {
 | |
|       return textsecure.storage.protocol.getGroup(groupId).then(group => {
 | |
|         if (group === undefined) return undefined;
 | |
| 
 | |
|         return { id: groupId, numbers: group.numbers };
 | |
|       });
 | |
|     },
 | |
| 
 | |
|     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);
 | |
|       });
 | |
|     },
 | |
|   };
 | |
| })();
 |