diff --git a/lib/shared/state-sync/current-user-state-sync-spec.js b/lib/shared/state-sync/current-user-state-sync-spec.js index 11fdb94df..dcd1d3bf4 100644 --- a/lib/shared/state-sync/current-user-state-sync-spec.js +++ b/lib/shared/state-sync/current-user-state-sync-spec.js @@ -1,40 +1,28 @@ // @flow import { createSelector } from 'reselect'; import type { StateSyncSpec } from './state-sync-spec.js'; import type { AppState } from '../../types/redux-types'; -import { - type CurrentUserInfo, - currentUserInfoValidator, -} from '../../types/user-types.js'; -import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js'; +import { type CurrentUserInfo } from '../../types/user-types.js'; import { hash } from '../../utils/objects.js'; -import { ashoatKeyserverID } from '../../utils/validation-utils.js'; export const currentUserStateSyncSpec: StateSyncSpec< CurrentUserInfo, CurrentUserInfo, void, > = Object.freeze({ hashKey: 'currentUserInfo', - convertClientToServerInfos(info: CurrentUserInfo) { - return convertClientIDsToServerIDs( - ashoatKeyserverID, - currentUserInfoValidator, - info, - ); - }, findStoreInconsistencies() { return undefined; }, selector: createSelector( (state: AppState) => state.currentUserInfo, currentUserInfo => ({ ...currentUserStateSyncSpec, getInfoHash: () => hash(currentUserInfo), getAllInfosHash: () => hash(currentUserInfo), getIDs: () => [], }), ), }); diff --git a/lib/shared/state-sync/entries-state-sync-spec.js b/lib/shared/state-sync/entries-state-sync-spec.js index c61a7f3a5..60f6762c9 100644 --- a/lib/shared/state-sync/entries-state-sync-spec.js +++ b/lib/shared/state-sync/entries-state-sync-spec.js @@ -1,125 +1,107 @@ // @flow import _isEqual from 'lodash/fp/isEqual.js'; import { createSelector } from 'reselect'; -import t from 'tcomb'; import type { StateSyncSpec } from './state-sync-spec.js'; import { type CalendarQuery, type RawEntryInfos, - rawEntryInfoValidator, type RawEntryInfo, } from '../../types/entry-types.js'; import type { AppState } from '../../types/redux-types.js'; import { reportTypes, type ClientEntryInconsistencyReportCreationRequest, } from '../../types/report-types.js'; import type { ProcessServerRequestAction } from '../../types/request-types.js'; import { actionLogger } from '../../utils/action-logger.js'; import { getConfig } from '../../utils/config.js'; -import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js'; import { values, combineUnorderedHashes, hash } from '../../utils/objects.js'; import { generateReportID } from '../../utils/report-utils.js'; import { sanitizeActionSecrets } from '../../utils/sanitization.js'; -import { ashoatKeyserverID, tID } from '../../utils/validation-utils.js'; +import { ashoatKeyserverID } from '../../utils/validation-utils.js'; import { filterRawEntryInfosByCalendarQuery, serverEntryInfosObject, } from '../entry-utils.js'; export const entriesStateSyncSpec: StateSyncSpec< RawEntryInfos, RawEntryInfo, $ReadOnlyArray, > = Object.freeze({ hashKey: 'entryInfos', innerHashSpec: { hashKey: 'entryInfo', deleteKey: 'deleteEntryIDs', rawInfosKey: 'rawEntryInfos', }, - convertClientToServerInfos( - infos: RawEntryInfos, - calendarQuery: CalendarQuery, - ) { - const filteredEntryInfos = filterRawEntryInfosByCalendarQuery( - serverEntryInfosObject(values(infos)), - calendarQuery, - ); - - return convertClientIDsToServerIDs( - ashoatKeyserverID, - t.dict(tID, rawEntryInfoValidator), - filteredEntryInfos, - ); - }, findStoreInconsistencies( action: ProcessServerRequestAction, beforeStateCheck: RawEntryInfos, afterStateCheck: RawEntryInfos, ) { const calendarQuery = action.payload.calendarQuery; // We don't want to bother reporting an inconsistency if it's just because // of extraneous EntryInfos (not within the current calendarQuery) on either // side const filteredBeforeResult = filterRawEntryInfosByCalendarQuery( serverEntryInfosObject(values(beforeStateCheck)), calendarQuery, ); const filteredAfterResult = filterRawEntryInfosByCalendarQuery( serverEntryInfosObject(values(afterStateCheck)), calendarQuery, ); if (_isEqual(filteredBeforeResult)(filteredAfterResult)) { return emptyArray; } return [ { type: reportTypes.ENTRY_INCONSISTENCY, platformDetails: getConfig().platformDetails, beforeAction: beforeStateCheck, action: sanitizeActionSecrets(action), calendarQuery, pushResult: afterStateCheck, lastActions: actionLogger.interestingActionSummaries, time: Date.now(), id: generateReportID(), }, ]; }, selector: createSelector( (state: AppState) => state.entryStore.entryInfos, entryInfos => ({ ...entriesStateSyncSpec, getInfoHash: id => hash(entryInfos[`${ashoatKeyserverID}|${id}`]), getAllInfosHash: calendarQuery => getEntryInfosHash(entryInfos, calendarQuery), getIDs: calendarQuery => getEntryIDs(entryInfos, calendarQuery), }), ), }); const emptyArray = []; function getEntryInfosHash( entryInfos: RawEntryInfos, calendarQuery: CalendarQuery, ) { const filteredEntryInfos = filterRawEntryInfosByCalendarQuery( serverEntryInfosObject(values(entryInfos)), calendarQuery, ); return combineUnorderedHashes(Object.values(filteredEntryInfos).map(hash)); } function getEntryIDs(entryInfos: RawEntryInfos, calendarQuery: CalendarQuery) { const filteredEntryInfos = filterRawEntryInfosByCalendarQuery( serverEntryInfosObject(values(entryInfos)), calendarQuery, ); return Object.keys(filteredEntryInfos).map(id => id.split('|')[1]); } diff --git a/lib/shared/state-sync/state-sync-spec.js b/lib/shared/state-sync/state-sync-spec.js index 2cf1d4ddd..e5809c154 100644 --- a/lib/shared/state-sync/state-sync-spec.js +++ b/lib/shared/state-sync/state-sync-spec.js @@ -1,39 +1,35 @@ // @flow import type { CalendarQuery } from '../../types/entry-types.js'; import type { AppState } from '../../types/redux-types.js'; import type { ProcessServerRequestAction } from '../../types/request-types.js'; export type StateSyncSpec = { +hashKey: string, +innerHashSpec?: { +hashKey: string, +deleteKey: string, +rawInfosKey: string, +additionalDeleteCondition?: Info => boolean, }, - +convertClientToServerInfos: ( - infos: Infos, - calendarQuery: CalendarQuery, - ) => Infos, +findStoreInconsistencies: ( action: ProcessServerRequestAction, beforeStateCheck: Infos, afterStateCheck: Infos, ) => Inconsistencies, +selector: ( state: AppState, ) => BoundStateSyncSpec, }; // All ids specified here (getInfoHash and getIDs) are server ids. // E.g. in the case of threadStore or entryStore the keyserver prefix // needs to be handled additionaly export type BoundStateSyncSpec = { // If these function depend on background hashing that is still not complete // they should return null, to indicate that the hashes aren't available yet +getInfoHash: (id: string) => ?number, +getAllInfosHash: (query: CalendarQuery) => ?number, +getIDs: (query: CalendarQuery) => ?Array, ...StateSyncSpec, }; diff --git a/lib/shared/state-sync/threads-state-sync-spec.js b/lib/shared/state-sync/threads-state-sync-spec.js index 36ce61cac..0f54d58eb 100644 --- a/lib/shared/state-sync/threads-state-sync-spec.js +++ b/lib/shared/state-sync/threads-state-sync-spec.js @@ -1,83 +1,73 @@ // @flow import _isEqual from 'lodash/fp/isEqual.js'; import { createSelector } from 'reselect'; -import t from 'tcomb'; import type { StateSyncSpec } from './state-sync-spec.js'; import type { AppState } from '../../types/redux-types.js'; import { reportTypes, type ClientThreadInconsistencyReportCreationRequest, } from '../../types/report-types.js'; import type { ProcessServerRequestAction } from '../../types/request-types.js'; import { type RawThreadInfos, type RawThreadInfo, - rawThreadInfoValidator, } from '../../types/thread-types.js'; import { actionLogger } from '../../utils/action-logger.js'; import { getConfig } from '../../utils/config.js'; -import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js'; import { combineUnorderedHashes, values } from '../../utils/objects.js'; import { generateReportID } from '../../utils/report-utils.js'; import { sanitizeActionSecrets } from '../../utils/sanitization.js'; -import { ashoatKeyserverID, tID } from '../../utils/validation-utils.js'; +import { ashoatKeyserverID } from '../../utils/validation-utils.js'; export const threadsStateSyncSpec: StateSyncSpec< RawThreadInfos, RawThreadInfo, $ReadOnlyArray, > = Object.freeze({ hashKey: 'threadInfos', innerHashSpec: { hashKey: 'threadInfo', deleteKey: 'deleteThreadIDs', rawInfosKey: 'rawThreadInfos', }, - convertClientToServerInfos(infos: RawThreadInfos) { - return convertClientIDsToServerIDs( - ashoatKeyserverID, - t.dict(tID, rawThreadInfoValidator), - infos, - ); - }, findStoreInconsistencies( action: ProcessServerRequestAction, beforeStateCheck: RawThreadInfos, afterStateCheck: RawThreadInfos, ) { if (_isEqual(beforeStateCheck)(afterStateCheck)) { return emptyArray; } return [ { type: reportTypes.THREAD_INCONSISTENCY, platformDetails: getConfig().platformDetails, beforeAction: beforeStateCheck, action: sanitizeActionSecrets(action), pushResult: afterStateCheck, lastActions: actionLogger.interestingActionSummaries, time: Date.now(), id: generateReportID(), }, ]; }, selector: createSelector( (state: AppState) => state.integrityStore.threadHashes, (state: AppState) => state.integrityStore.threadHashingStatus === 'completed', (threadHashes, threadHashingComplete) => ({ ...threadsStateSyncSpec, getInfoHash: id => threadHashes[`${ashoatKeyserverID}|${id}`], getAllInfosHash: threadHashingComplete ? () => combineUnorderedHashes(values(threadHashes)) : () => null, getIDs: threadHashingComplete ? () => Object.keys(threadHashes).map(id => id.split('|')[1]) : () => null, }), ), }); const emptyArray = []; diff --git a/lib/shared/state-sync/users-state-sync-spec.js b/lib/shared/state-sync/users-state-sync-spec.js index 5e13df419..8614c67c4 100644 --- a/lib/shared/state-sync/users-state-sync-spec.js +++ b/lib/shared/state-sync/users-state-sync-spec.js @@ -1,80 +1,67 @@ // @flow import _isEqual from 'lodash/fp/isEqual.js'; import { createSelector } from 'reselect'; import type { StateSyncSpec } from './state-sync-spec.js'; import type { AppState } from '../../types/redux-types'; import { reportTypes, type UserInconsistencyReportCreationRequest, } from '../../types/report-types.js'; import type { ProcessServerRequestAction } from '../../types/request-types.js'; -import { - type UserInfo, - type UserInfos, - userInfosValidator, -} from '../../types/user-types.js'; +import { type UserInfo, type UserInfos } from '../../types/user-types.js'; import { actionLogger } from '../../utils/action-logger.js'; import { getConfig } from '../../utils/config.js'; -import { convertClientIDsToServerIDs } from '../../utils/conversion-utils.js'; import { combineUnorderedHashes, hash } from '../../utils/objects.js'; import { generateReportID } from '../../utils/report-utils.js'; import { sanitizeActionSecrets } from '../../utils/sanitization.js'; -import { ashoatKeyserverID } from '../../utils/validation-utils.js'; export const usersStateSyncSpec: StateSyncSpec< UserInfos, UserInfo, $ReadOnlyArray, > = Object.freeze({ hashKey: 'userInfos', innerHashSpec: { hashKey: 'userInfo', deleteKey: 'deleteUserInfoIDs', rawInfosKey: 'userInfos', additionalDeleteCondition(user: UserInfo) { return !user.username; }, }, - convertClientToServerInfos(infos: UserInfos) { - return convertClientIDsToServerIDs( - ashoatKeyserverID, - userInfosValidator, - infos, - ); - }, findStoreInconsistencies( action: ProcessServerRequestAction, beforeStateCheck: UserInfos, afterStateCheck: UserInfos, ) { if (_isEqual(beforeStateCheck)(afterStateCheck)) { return emptyArray; } return [ { type: reportTypes.USER_INCONSISTENCY, platformDetails: getConfig().platformDetails, action: sanitizeActionSecrets(action), beforeStateCheck, afterStateCheck, lastActions: actionLogger.interestingActionSummaries, time: Date.now(), id: generateReportID(), }, ]; }, selector: createSelector( (state: AppState) => state.userStore.userInfos, userInfos => ({ ...usersStateSyncSpec, getInfoHash: id => hash(userInfos[id]), getAllInfosHash: () => combineUnorderedHashes(Object.values(userInfos).map(hash)), getIDs: () => Object.keys(userInfos), }), ), }); const emptyArray = [];