diff --git a/lib/actions/activity-actions.js b/lib/actions/activity-actions.js --- a/lib/actions/activity-actions.js +++ b/lib/actions/activity-actions.js @@ -1,5 +1,7 @@ // @flow +import invariant from 'invariant'; + import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js'; import { useKeyserverCall } from '../keyserver-conn/keyserver-call.js'; import type { CallKeyserverEndpoint } from '../keyserver-conn/keyserver-conn-types.js'; @@ -27,7 +29,9 @@ const { activityUpdates } = input; const requests: { [string]: { +updates: ActivityUpdate[] } } = {}; for (const update of activityUpdates) { - const keyserverID = extractKeyserverIDFromID(update.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(update.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; if (!requests[keyserverID]) { requests[keyserverID] = { updates: [] }; } @@ -76,7 +80,9 @@ input: SetThreadUnreadStatusRequest, ) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( diff --git a/lib/actions/community-actions.js b/lib/actions/community-actions.js --- a/lib/actions/community-actions.js +++ b/lib/actions/community-actions.js @@ -1,5 +1,7 @@ // @flow +import invariant from 'invariant'; + import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js'; import { useKeyserverCall } from '../keyserver-conn/keyserver-call.js'; import type { CallKeyserverEndpoint } from '../keyserver-conn/keyserver-conn-types.js'; @@ -72,7 +74,9 @@ input: CreateOrUpdateFarcasterChannelTagRequest, ) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.commCommunityID); + const optionalKeyserverID = extractKeyserverIDFromID(input.commCommunityID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { @@ -113,7 +117,9 @@ input: DeleteFarcasterChannelTagRequest, ) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.commCommunityID); + const optionalKeyserverID = extractKeyserverIDFromID(input.commCommunityID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { diff --git a/lib/actions/entry-actions.js b/lib/actions/entry-actions.js --- a/lib/actions/entry-actions.js +++ b/lib/actions/entry-actions.js @@ -1,5 +1,7 @@ // @flow +import invariant from 'invariant'; + import { extractKeyserverIDFromID, sortCalendarQueryPerKeyserver, @@ -156,7 +158,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: CreateEntryInfo) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const calendarQueries = sortCalendarQueryPerKeyserver(input.calendarQuery, [ keyserverID, ]); @@ -195,7 +199,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: SaveEntryInfo) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.entryID); + const optionalKeyserverID = extractKeyserverIDFromID(input.entryID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const calendarQueries = sortCalendarQueryPerKeyserver(input.calendarQuery, [ keyserverID, ]); @@ -229,7 +235,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((info: DeleteEntryInfo) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.entryID); + const optionalKeyserverID = extractKeyserverIDFromID(input.entryID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const calendarQueries = sortCalendarQueryPerKeyserver(input.calendarQuery, [ keyserverID, ]); @@ -271,7 +279,9 @@ input: FetchRevisionsForEntryInput, ) => Promise<$ReadOnlyArray>) => async input => { - const keyserverID = extractKeyserverIDFromID(input.entryID); + const optionalKeyserverID = extractKeyserverIDFromID(input.entryID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { id: input.entryID, @@ -301,7 +311,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: RestoreEntryInfo) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.entryID); + const optionalKeyserverID = extractKeyserverIDFromID(input.entryID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const calendarQueries = sortCalendarQueryPerKeyserver(input.calendarQuery, [ keyserverID, ]); diff --git a/lib/actions/link-actions.js b/lib/actions/link-actions.js --- a/lib/actions/link-actions.js +++ b/lib/actions/link-actions.js @@ -1,4 +1,5 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import type { CallSingleKeyserverEndpoint } from '../keyserver-conn/call-single-keyserver-endpoint.js'; @@ -129,7 +130,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: CreateOrUpdatePublicLinkRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.communityID); + const optionalKeyserverID = extractKeyserverIDFromID(input.communityID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { name: input.name, @@ -170,7 +173,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: DisableInviteLinkRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.communityID); + const optionalKeyserverID = extractKeyserverIDFromID(input.communityID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; await callKeyserverEndpoint('disable_invite_link', requests); diff --git a/lib/actions/message-actions.js b/lib/actions/message-actions.js --- a/lib/actions/message-actions.js +++ b/lib/actions/message-actions.js @@ -48,7 +48,9 @@ async input => { const { threadID, beforeMessageID } = input; - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { cursors: { @@ -89,7 +91,9 @@ async input => { const { threadID } = input; - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { cursors: { @@ -189,7 +193,9 @@ payload = { ...payload, sidebarCreation }; } - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: payload }; const responses = await callKeyserverEndpoint( @@ -248,7 +254,9 @@ payload = { ...payload, sidebarCreation }; } - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: payload }; const responses = await callKeyserverEndpoint( @@ -300,7 +308,9 @@ payload = { ...payload, sidebarCreation }; } - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: payload }; const responses = await callKeyserverEndpoint( @@ -343,7 +353,9 @@ resultInfo = passedResultInfo; }; - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { threadID: input.threadID, @@ -389,7 +401,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: SendEditMessageRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.targetMessageID); + const optionalKeyserverID = extractKeyserverIDFromID(input.targetMessageID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { targetMessageID: input.targetMessageID, @@ -426,7 +440,9 @@ input: FetchPinnedMessagesRequest, ) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( @@ -454,7 +470,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: SearchMessagesRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint('search_messages', requests); @@ -481,7 +499,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: ToggleMessagePinRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.messageID); + const optionalKeyserverID = extractKeyserverIDFromID(input.messageID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( diff --git a/lib/actions/message-report-actions.js b/lib/actions/message-report-actions.js --- a/lib/actions/message-report-actions.js +++ b/lib/actions/message-report-actions.js @@ -1,5 +1,7 @@ // @flow +import invariant from 'invariant'; + import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js'; import { useKeyserverCall } from '../keyserver-conn/keyserver-call.js'; import type { CallKeyserverEndpoint } from '../keyserver-conn/keyserver-conn-types.js'; @@ -20,7 +22,9 @@ input: MessageReportCreationRequest, ) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.messageID); + const optionalKeyserverID = extractKeyserverIDFromID(input.messageID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( diff --git a/lib/actions/thread-actions.js b/lib/actions/thread-actions.js --- a/lib/actions/thread-actions.js +++ b/lib/actions/thread-actions.js @@ -43,7 +43,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: DeleteThreadInput) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( @@ -81,7 +83,9 @@ Object.keys(input.changes).length > 0, 'No changes provided to changeThreadSettings!', ); - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( @@ -125,7 +129,9 @@ input: RemoveUsersFromThreadInput, ) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( @@ -171,7 +177,9 @@ ) => Promise) => async input => { const { threadID, memberIDs, newRole } = input; - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { threadID, @@ -210,7 +218,9 @@ ): ((input: ClientNewThinThreadRequest) => Promise) => async input => { const parentThreadID = input.parentThreadID ?? genesis().id; - const keyserverID = extractKeyserverIDFromID(parentThreadID); + const optionalKeyserverID = extractKeyserverIDFromID(parentThreadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint('create_thread', requests); @@ -240,7 +250,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: ClientThreadJoinRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint('join_thread', requests); @@ -274,7 +286,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: LeaveThreadInput) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint('leave_thread', requests); @@ -295,7 +309,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: ThreadFetchMediaRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( @@ -322,7 +338,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: RoleModificationRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.community); + const optionalKeyserverID = extractKeyserverIDFromID(input.community); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( @@ -352,7 +370,9 @@ callKeyserverEndpoint: CallKeyserverEndpoint, ): ((input: RoleDeletionRequest) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.community); + const optionalKeyserverID = extractKeyserverIDFromID(input.community); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js --- a/lib/actions/upload-actions.js +++ b/lib/actions/upload-actions.js @@ -115,7 +115,10 @@ ): ((input: DeleteUploadInput) => Promise) => async input => { const { id, keyserverOrThreadID } = input; - const keyserverID = extractKeyserverIDFromID(keyserverOrThreadID); + const optionalKeyserverID = + extractKeyserverIDFromID(keyserverOrThreadID) ?? keyserverOrThreadID; + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { id } }; await callKeyserverEndpoint('delete_upload', requests); }; @@ -224,7 +227,10 @@ } // 3. Upload metadata to keyserver - const keyserverID = extractKeyserverIDFromID(keyserverOrThreadID); + const optionalKeyserverID = + extractKeyserverIDFromID(keyserverOrThreadID) ?? keyserverOrThreadID; + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: { blobHash, diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -1149,7 +1149,9 @@ input: SubscriptionUpdateRequest, ) => Promise) => async input => { - const keyserverID = extractKeyserverIDFromID(input.threadID); + const optionalKeyserverID = extractKeyserverIDFromID(input.threadID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + const keyserverID: string = optionalKeyserverID; const requests = { [keyserverID]: input }; const responses = await callKeyserverEndpoint( diff --git a/lib/hooks/invite-links.js b/lib/hooks/invite-links.js --- a/lib/hooks/invite-links.js +++ b/lib/hooks/invite-links.js @@ -1,5 +1,6 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import { addKeyserverActionType } from '../actions/keyserver-actions.js'; @@ -184,7 +185,9 @@ const communityID = verificationResponse.community?.id; let keyserverID = keyserverOverride?.keyserverID; if (!keyserverID && communityID) { - keyserverID = extractKeyserverIDFromID(communityID); + const optionalKeyserverID = extractKeyserverIDFromID(communityID); + invariant(optionalKeyserverID, 'Keyserver ID should be present'); + keyserverID = optionalKeyserverID; } const isKeyserverKnown = useSelector(state => diff --git a/lib/keyserver-conn/keyserver-call-utils.js b/lib/keyserver-conn/keyserver-call-utils.js --- a/lib/keyserver-conn/keyserver-call-utils.js +++ b/lib/keyserver-conn/keyserver-call-utils.js @@ -5,7 +5,10 @@ import type { CalendarQuery } from '../types/entry-types.js'; import type { NotDeletedFilter } from '../types/filter-types.js'; -function extractKeyserverIDFromID(id: string): string { +function extractKeyserverIDFromID(id: string): ?string { + if (!id.includes('|')) { + return null; + } return id.split('|')[0]; } @@ -14,8 +17,9 @@ } { const results: { [string]: string[] } = {}; for (const threadID of threadIDs) { - const keyserverID = extractKeyserverIDFromID(threadID); - invariant(keyserverID, 'keyserver data missing from thread id'); + const optionalKeyserverID = extractKeyserverIDFromID(threadID); + invariant(optionalKeyserverID, 'keyserver data missing from thread id'); + const keyserverID: string = optionalKeyserverID; if (results[keyserverID] === undefined) { results[keyserverID] = []; } @@ -61,7 +65,7 @@ } else if (filter.type === 'threads') { for (const threadID of filter.threadIDs) { const keyserverID = extractKeyserverIDFromID(threadID); - if (results[keyserverID] === undefined) { + if (!keyserverID || results[keyserverID] === undefined) { continue; } let threadFilter = results[keyserverID].filters.find( @@ -94,9 +98,10 @@ return []; } const keyserverIDsSet = new Set(keyserverIDs); - return threadIDs.filter(threadID => - keyserverIDsSet.has(extractKeyserverIDFromID(threadID)), - ); + return threadIDs.filter(threadID => { + const keyserverID = extractKeyserverIDFromID(threadID); + return keyserverID && keyserverIDsSet.has(keyserverID); + }); } export { diff --git a/lib/keyserver-conn/keyserver-call-utils.test.js b/lib/keyserver-conn/keyserver-call-utils.test.js --- a/lib/keyserver-conn/keyserver-call-utils.test.js +++ b/lib/keyserver-conn/keyserver-call-utils.test.js @@ -14,9 +14,9 @@ expect(extractKeyserverIDFromID(id)).toBe(keyserverID); }); - it('should return for ', () => { - const keyserverID = '404'; - expect(extractKeyserverIDFromID(keyserverID)).toBe(keyserverID); + it('should return null for non-keyserver ID', () => { + const id = '404'; + expect(extractKeyserverIDFromID(id)).toBe(null); }); }); diff --git a/lib/reducers/calendar-filters-reducer.js b/lib/reducers/calendar-filters-reducer.js --- a/lib/reducers/calendar-filters-reducer.js +++ b/lib/reducers/calendar-filters-reducer.js @@ -220,8 +220,10 @@ keyserverIDs: $ReadOnlyArray, ): $ReadOnlyArray { const keyserverIDsSet = new Set(keyserverIDs); - const filterCondition = (threadID: string) => - !keyserverIDsSet.has(extractKeyserverIDFromID(threadID)); + const filterCondition = (threadID: string) => { + const keyserverID = extractKeyserverIDFromID(threadID); + return !keyserverID || !keyserverIDsSet.has(keyserverID); + }; return filterThreadIDsInFilterList(state, filterCondition); } diff --git a/lib/reducers/draft-reducer.js b/lib/reducers/draft-reducer.js --- a/lib/reducers/draft-reducer.js +++ b/lib/reducers/draft-reducer.js @@ -25,7 +25,8 @@ const drafts: { [key: string]: string } = {}; const ids: string[] = []; for (const key in draftStore.drafts) { - if (keyserverIDsSet.has(extractKeyserverIDFromID(key))) { + const keyserverID = extractKeyserverIDFromID(key); + if (keyserverID && keyserverIDsSet.has(keyserverID)) { ids.push(key); } else { drafts[key] = draftStore.drafts[key]; diff --git a/lib/reducers/invite-links-reducer.js b/lib/reducers/invite-links-reducer.js --- a/lib/reducers/invite-links-reducer.js +++ b/lib/reducers/invite-links-reducer.js @@ -60,7 +60,8 @@ const keyserverIDsSet = new Set(action.payload.keyserverIDs); const newLinks: { [communityID: string]: CommunityLinks } = {}; for (const linkID in state.links) { - if (!keyserverIDsSet.has(extractKeyserverIDFromID(linkID))) { + const keyserverID = extractKeyserverIDFromID(linkID); + if (!keyserverID || !keyserverIDsSet.has(keyserverID)) { newLinks[linkID] = state.links[linkID]; } } diff --git a/lib/reducers/thread-activity-reducer.js b/lib/reducers/thread-activity-reducer.js --- a/lib/reducers/thread-activity-reducer.js +++ b/lib/reducers/thread-activity-reducer.js @@ -183,7 +183,8 @@ const keyserverIDsSet = new Set(action.payload.keyserverIDs); for (const threadID in state) { - if (!keyserverIDsSet.has(extractKeyserverIDFromID(threadID))) { + const keyserverID = extractKeyserverIDFromID(threadID); + if (!keyserverID || !keyserverIDsSet.has(keyserverID)) { continue; } threadIDsToRemove.push(threadID); diff --git a/lib/shared/message-utils.js b/lib/shared/message-utils.js --- a/lib/shared/message-utils.js +++ b/lib/shared/message-utils.js @@ -664,8 +664,9 @@ const keyserverID = extractKeyserverIDFromID(messageInfo.threadID); if ( - !timePerKeyserver[keyserverID] || - timePerKeyserver[keyserverID] < messageInfo.time + keyserverID && + (!timePerKeyserver[keyserverID] || + timePerKeyserver[keyserverID] < messageInfo.time) ) { timePerKeyserver[keyserverID] = messageInfo.time; } diff --git a/native/calendar/entry.react.js b/native/calendar/entry.react.js --- a/native/calendar/entry.react.js +++ b/native/calendar/entry.react.js @@ -810,10 +810,17 @@ const threadInfo = useResolvedThreadInfo(unresolvedThreadInfo); const keyserverID = extractKeyserverIDFromID(threadInfo.id); - const connection = useSelector(connectionSelector(keyserverID)); + const connection = useSelector(state => { + if (!keyserverID) { + return { + status: 'connected', + }; + } + return connectionSelector(keyserverID)(state); + }); invariant( connection, - `keyserver ${keyserverID} missing from keyserverStore`, + `keyserver ${keyserverID ?? 'null'} missing from keyserverStore`, ); const online = connection.status === 'connected'; diff --git a/native/chat/settings/thread-settings-push-notifs.react.js b/native/chat/settings/thread-settings-push-notifs.react.js --- a/native/chat/settings/thread-settings-push-notifs.react.js +++ b/native/chat/settings/thread-settings-push-notifs.react.js @@ -176,7 +176,12 @@ props: BaseProps, ) { const keyserverID = extractKeyserverIDFromID(props.threadInfo.id); - const deviceToken = useSelector(deviceTokenSelector(keyserverID)); + const deviceToken = useSelector(state => { + if (!keyserverID) { + return state.tunnelbrokerDeviceToken; + } + return deviceTokenSelector(keyserverID)(state); + }); const hasPushPermissions = deviceToken !== null && deviceToken !== undefined; const styles = useStyles(unboundStyles); diff --git a/native/components/auto-join-community-handler.react.js b/native/components/auto-join-community-handler.react.js --- a/native/components/auto-join-community-handler.react.js +++ b/native/components/auto-join-community-handler.react.js @@ -128,7 +128,7 @@ const { commCommunityID } = await blobResult.json(); const keyserverID = extractKeyserverIDFromID(commCommunityID); - if (!keyserverInfos[keyserverID]) { + if (!keyserverID || !keyserverInfos[keyserverID]) { return; } diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -1,6 +1,7 @@ // @flow import * as Haptics from 'expo-haptics'; +import invariant from 'invariant'; import _groupBy from 'lodash/fp/groupBy.js'; import * as React from 'react'; import { LogBox, Platform } from 'react-native'; @@ -755,6 +756,7 @@ this.saveMessageInfos(messageInfos); const keyserverID = extractKeyserverIDFromID(message.threadID); + invariant(keyserverID, 'Keyserver ID should be present'); const updateCurrentAsOf = this.props.allUpdatesCurrentAsOf[keyserverID]; handleAndroidMessage( diff --git a/web/calendar/entry.react.js b/web/calendar/entry.react.js --- a/web/calendar/entry.react.js +++ b/web/calendar/entry.react.js @@ -474,10 +474,17 @@ ); const calendarQuery = useSelector(nonThreadCalendarQuery); const keyserverID = extractKeyserverIDFromID(threadID); - const connection = useSelector(connectionSelector(keyserverID)); + const connection = useSelector(state => { + if (!keyserverID) { + return { + status: 'connected', + }; + } + return connectionSelector(keyserverID)(state); + }); invariant( connection, - `keyserver ${keyserverID} missing from keyserverStore`, + `keyserver ${keyserverID ?? 'null'} missing from keyserverStore`, ); const online = connection.status === 'connected'; const callCreateEntry = useCreateEntry();