2020-10-30 15:34:04 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Copyright 2020 Signal Messenger, LLC
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// SPDX-License-Identifier: AGPL-3.0-only
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import { last, sortBy } from 'lodash';
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import { AuthCredentialWithPniResponse } from '@signalapp/libsignal-client/zkgroup';
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-11 07:24:28 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import { getClientZkAuthOperations } from '../util/zkgroup';
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-10-26 14:15:33 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import type { GroupCredentialType } from '../textsecure/WebAPI';
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import { strictAssert } from '../util/assert';
							 | 
						
					
						
							
								
									
										
										
										
											2021-08-26 09:10:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import * as durations from '../util/durations';
							 | 
						
					
						
							
								
									
										
										
										
											2021-06-09 15:28:54 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import { BackOff } from '../util/BackOff';
							 | 
						
					
						
							
								
									
										
										
										
											2020-10-13 17:21:42 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import { sleep } from '../util/sleep';
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import { toDayMillis } from '../util/timestamp';
							 | 
						
					
						
							
								
									
										
										
										
											2021-11-30 20:33:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import { UUIDKind } from '../types/UUID';
							 | 
						
					
						
							
								
									
										
										
										
											2021-09-17 14:27:53 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import * as log from '../logging/log';
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								export const GROUP_CREDENTIALS_KEY = 'groupCredentials';
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-28 09:35:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								type CredentialsDataType = ReadonlyArray<GroupCredentialType>;
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type RequestDatesType = {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  startDayInMs: number;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  endDayInMs: number;
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type NextCredentialsType = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  today: GroupCredentialType;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  tomorrow: GroupCredentialType;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								let started = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								function getCheckedCredentials(reason: string): CredentialsDataType {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const result = window.storage.get('groupCredentials');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  strictAssert(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    result !== undefined,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    `getCheckedCredentials: no credentials found, ${reason}`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return result;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								export async function initializeGroupCredentialFetcher(): Promise<void> {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (started) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-09-17 14:27:53 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  log.info('initializeGroupCredentialFetcher: starting...');
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  started = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // Because we fetch eight days of credentials at a time, we really only need to run
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  //   this about once a week. But there's no problem running it more often; it will do
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  //   nothing if no new credentials are needed, and will only request needed credentials.
							 | 
						
					
						
							
								
									
										
										
										
											2021-08-26 09:10:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  await runWithRetry(maybeFetchNewCredentials, {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    scheduleAnother: 4 * durations.HOUR,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  });
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-06-09 15:28:54 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								const BACKOFF_TIMEOUTS = [
							 | 
						
					
						
							
								
									
										
										
										
											2021-08-26 09:10:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  durations.SECOND,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  5 * durations.SECOND,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  30 * durations.SECOND,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  2 * durations.MINUTE,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  5 * durations.MINUTE,
							 | 
						
					
						
							
								
									
										
										
										
											2021-06-09 15:28:54 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								];
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								export async function runWithRetry(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  fn: () => Promise<void>,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  options: { scheduleAnother?: number } = {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								): Promise<void> {
							 | 
						
					
						
							
								
									
										
										
										
											2021-06-09 15:28:54 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const backOff = new BackOff(BACKOFF_TIMEOUTS);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // eslint-disable-next-line no-constant-condition
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  while (true) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    try {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      // eslint-disable-next-line no-await-in-loop
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      await fn();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    } catch (error) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-06-09 15:28:54 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      const wait = backOff.getAndIncrement();
							 | 
						
					
						
							
								
									
										
										
										
											2021-09-17 14:27:53 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      log.info(
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        `runWithRetry: ${fn.name} failed. Waiting ${wait}ms for retry. Error: ${error.stack}`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      // eslint-disable-next-line no-await-in-loop
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      await sleep(wait);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // It's important to schedule our next run here instead of the level above; otherwise we
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  //   could end up with multiple endlessly-retrying runs.
							 | 
						
					
						
							
								
									
										
										
										
											2022-09-15 12:17:15 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  // eslint-disable-next-line no-unreachable -- Why is this here, its unreachable
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const duration = options.scheduleAnother;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (duration) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-09-17 14:27:53 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    log.info(
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      `runWithRetry: scheduling another run with a setTimeout duration of ${duration}ms`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    setTimeout(async () => runWithRetry(fn, options), duration);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// In cases where we are at a day boundary, we might need to use tomorrow in a retry
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								export function getCheckedCredentialsForToday(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  reason: string
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								): NextCredentialsType {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const data = getCheckedCredentials(reason);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const today = toDayMillis(Date.now());
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const todayIndex = data.findIndex(
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    (item: GroupCredentialType) => item.redemptionTime === today
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (todayIndex < 0) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    throw new Error(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      'getCredentialsForToday: Cannot find credentials for today'
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    today: data[todayIndex],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    tomorrow: data[todayIndex + 1],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								export async function maybeFetchNewCredentials(): Promise<void> {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const logId = 'maybeFetchNewCredentials';
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const aci = window.textsecure.storage.user.getUuid(UUIDKind.ACI)?.toString();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (!aci) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log.info(`${logId}: no ACI, returning early`);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const previous: CredentialsDataType | undefined =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    window.storage.get('groupCredentials');
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const requestDates = getDatesForRequest(previous);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (!requestDates) {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    log.info(`${logId}: no new credentials needed`);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const { server } = window.textsecure;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (!server) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log.error(`${logId}: unable to get server`);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const { startDayInMs, endDayInMs } = requestDates;
							 | 
						
					
						
							
								
									
										
										
										
											2021-09-17 14:27:53 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  log.info(
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    `${logId}: fetching credentials for ${startDayInMs} through ${endDayInMs}`
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const serverPublicParamsBase64 = window.getServerPublicParams();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const clientZKAuthOperations = getClientZkAuthOperations(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    serverPublicParamsBase64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-28 09:35:29 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const { pni, credentials: rawCredentials } = await server.getGroupCredentials(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    { startDayInMs, endDayInMs }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  strictAssert(pni, 'Server must give pni along with group credentials');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const localPni = window.storage.user.getUuid(UUIDKind.PNI);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  if (pni !== localPni?.toString()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    log.error(`${logId}: local PNI ${localPni}, does not match remote ${pni}`);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const newCredentials = sortCredentials(rawCredentials).map(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    (item: GroupCredentialType) => {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      const authCredential =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        clientZKAuthOperations.receiveAuthCredentialWithPni(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          aci,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          pni,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          item.redemptionTime,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          new AuthCredentialWithPniResponse(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            Buffer.from(item.credential, 'base64')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          )
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      const credential = authCredential.serialize().toString('base64');
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      return {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        redemptionTime: item.redemptionTime * durations.SECOND,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        credential,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  );
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const today = toDayMillis(Date.now());
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const previousCleaned = previous
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ? previous.filter(
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        (item: GroupCredentialType) => item.redemptionTime >= today
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      )
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    : [];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const finalCredentials = [...previousCleaned, ...newCredentials];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  log.info(`${logId}: Saving new credentials...`);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  // Note: we don't wait for this to finish
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  window.storage.put('groupCredentials', finalCredentials);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  log.info(`${logId}: Save complete.`);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								export function getDatesForRequest(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  data?: CredentialsDataType
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								): RequestDatesType | undefined {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const today = toDayMillis(Date.now());
							 | 
						
					
						
							
								
									
										
										
										
											2022-08-15 09:34:27 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  const sixDaysOut = today + 6 * durations.DAY;
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  const lastCredential = last(data);
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  if (!lastCredential || lastCredential.redemptionTime < today) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      startDayInMs: today,
							 | 
						
					
						
							
								
									
										
										
										
											2022-08-15 09:34:27 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      endDayInMs: sixDaysOut,
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2022-08-15 09:34:27 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  if (lastCredential.redemptionTime >= sixDaysOut) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return undefined;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return {
							 | 
						
					
						
							
								
									
										
										
										
											2022-07-08 13:46:25 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    startDayInMs: lastCredential.redemptionTime + durations.DAY,
							 | 
						
					
						
							
								
									
										
										
										
											2022-08-15 09:34:27 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    endDayInMs: sixDaysOut,
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								export function sortCredentials(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  data: CredentialsDataType
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								): CredentialsDataType {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  return sortBy(data, (item: GroupCredentialType) => item.redemptionTime);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |