Changeset View
Changeset View
Standalone View
Standalone View
keyserver/src/responders/website-responders.js
Show All 9 Lines | |||||
import { Route, StaticRouter } from 'react-router'; | import { Route, StaticRouter } from 'react-router'; | ||||
import { createStore, type Store } from 'redux'; | import { createStore, type Store } from 'redux'; | ||||
import { promisify } from 'util'; | import { promisify } from 'util'; | ||||
import { daysToEntriesFromEntryInfos } from 'lib/reducers/entry-reducer'; | import { daysToEntriesFromEntryInfos } from 'lib/reducers/entry-reducer'; | ||||
import { freshMessageStore } from 'lib/reducers/message-reducer'; | import { freshMessageStore } from 'lib/reducers/message-reducer'; | ||||
import { mostRecentlyReadThread } from 'lib/selectors/thread-selectors'; | import { mostRecentlyReadThread } from 'lib/selectors/thread-selectors'; | ||||
import { mostRecentMessageTimestamp } from 'lib/shared/message-utils'; | import { mostRecentMessageTimestamp } from 'lib/shared/message-utils'; | ||||
import { sortIDs } from 'lib/shared/relationship-utils'; | |||||
import { | import { | ||||
threadHasPermission, | threadHasPermission, | ||||
threadIsPending, | threadIsPending, | ||||
parsePendingThreadID, | parsePendingThreadID, | ||||
createPendingThread, | createPendingThread, | ||||
} from 'lib/shared/thread-utils'; | } from 'lib/shared/thread-utils'; | ||||
import { defaultWebEnabledApps } from 'lib/types/enabled-apps'; | import { defaultWebEnabledApps } from 'lib/types/enabled-apps'; | ||||
import { defaultCalendarFilters } from 'lib/types/filter-types'; | import { defaultCalendarFilters } from 'lib/types/filter-types'; | ||||
import { defaultNumberPerThread } from 'lib/types/message-types'; | import { defaultNumberPerThread } from 'lib/types/message-types'; | ||||
import { undirectedStatus } from 'lib/types/relationship-types'; | |||||
import { defaultEnabledReports } from 'lib/types/report-types'; | import { defaultEnabledReports } from 'lib/types/report-types'; | ||||
import { defaultConnectionInfo } from 'lib/types/socket-types'; | import { defaultConnectionInfo } from 'lib/types/socket-types'; | ||||
import { threadPermissions, threadTypes } from 'lib/types/thread-types'; | import { threadPermissions, threadTypes } from 'lib/types/thread-types'; | ||||
import type { CurrentUserInfo } from 'lib/types/user-types'; | import type { CurrentUserInfo } from 'lib/types/user-types'; | ||||
import { currentDateInTimeZone } from 'lib/utils/date-utils'; | import { currentDateInTimeZone } from 'lib/utils/date-utils'; | ||||
import { ServerError } from 'lib/utils/errors'; | import { ServerError } from 'lib/utils/errors'; | ||||
import { promiseAll } from 'lib/utils/promises'; | import { promiseAll } from 'lib/utils/promises'; | ||||
import { reducer } from 'web/redux/redux-setup'; | import { reducer } from 'web/redux/redux-setup'; | ||||
import type { AppState, Action } from 'web/redux/redux-setup'; | import type { AppState, Action } from 'web/redux/redux-setup'; | ||||
import getTitle from 'web/title/getTitle'; | import getTitle from 'web/title/getTitle'; | ||||
import { navInfoFromURL } from 'web/url-utils'; | import { navInfoFromURL } from 'web/url-utils'; | ||||
import { fetchEntryInfos } from '../fetchers/entry-fetchers'; | import { fetchEntryInfos } from '../fetchers/entry-fetchers'; | ||||
import { fetchMessageInfos } from '../fetchers/message-fetchers'; | import { fetchMessageInfos } from '../fetchers/message-fetchers'; | ||||
import { fetchThreadInfos } from '../fetchers/thread-fetchers'; | import { fetchThreadInfos } from '../fetchers/thread-fetchers'; | ||||
import { | import { | ||||
fetchCurrentUserInfo, | fetchCurrentUserInfo, | ||||
fetchKnownUserInfos, | fetchKnownUserInfos, | ||||
fetchUserInfos, | |||||
} from '../fetchers/user-fetchers'; | } from '../fetchers/user-fetchers'; | ||||
import { setNewSession } from '../session/cookies'; | import { setNewSession } from '../session/cookies'; | ||||
import { Viewer } from '../session/viewer'; | import { Viewer } from '../session/viewer'; | ||||
import { updateUndirectedRelationships } from '../updaters/relationship-updaters'; | |||||
import { streamJSON, waitForStream } from '../utils/json-stream'; | import { streamJSON, waitForStream } from '../utils/json-stream'; | ||||
import { | import { | ||||
getAppURLFactsFromRequestURL, | getAppURLFactsFromRequestURL, | ||||
clientPathFromRouterPath, | clientPathFromRouterPath, | ||||
} from '../utils/urls'; | } from '../utils/urls'; | ||||
const { renderToNodeStream } = ReactDOMServer; | const { renderToNodeStream } = ReactDOMServer; | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | ): Promise<void> { | ||||
try { | try { | ||||
initialNavInfo = navInfoFromURL(req.url, { | initialNavInfo = navInfoFromURL(req.url, { | ||||
now: currentDateInTimeZone(viewer.timeZone), | now: currentDateInTimeZone(viewer.timeZone), | ||||
}); | }); | ||||
} catch (e) { | } catch (e) { | ||||
throw new ServerError(e.message); | throw new ServerError(e.message); | ||||
} | } | ||||
let validUserIDsPromise, updateRelationshipsPromise; | |||||
if ( | |||||
viewer.loggedIn && | |||||
initialNavInfo.tab === 'chat' && | |||||
initialNavInfo.chatMode === 'create' && | |||||
initialNavInfo.selectedUserList && | |||||
initialNavInfo.selectedUserList.length > 0 | |||||
) { | |||||
const userIDs = initialNavInfo.selectedUserList; | |||||
validUserIDsPromise = (async () => { | |||||
const userInfos = await fetchUserInfos(userIDs); | |||||
return userIDs.filter(userID => !!userInfos[userID].username); | |||||
})(); | |||||
updateRelationshipsPromise = (async () => { | |||||
const validUserIDs = await validUserIDsPromise; | |||||
const rows = validUserIDs.map(userID => { | |||||
const [user1, user2] = sortIDs(viewer.userID, userID); | |||||
const status = undirectedStatus.KNOW_OF; | |||||
return { user1, user2, status }; | |||||
}); | |||||
await updateUndirectedRelationships(rows); | |||||
})(); | |||||
} | |||||
const calendarQuery = { | const calendarQuery = { | ||||
startDate: initialNavInfo.startDate, | startDate: initialNavInfo.startDate, | ||||
endDate: initialNavInfo.endDate, | endDate: initialNavInfo.endDate, | ||||
filters: defaultCalendarFilters, | filters: defaultCalendarFilters, | ||||
}; | }; | ||||
const messageSelectionCriteria = { joinedThreads: true }; | const messageSelectionCriteria = { joinedThreads: true }; | ||||
const initialTime = Date.now(); | const initialTime = Date.now(); | ||||
const assetInfoPromise = getAssetInfo(); | const assetInfoPromise = getAssetInfo(); | ||||
const threadInfoPromise = fetchThreadInfos(viewer); | const threadInfoPromise = fetchThreadInfos(viewer); | ||||
const messageInfoPromise = fetchMessageInfos( | const messageInfoPromise = fetchMessageInfos( | ||||
viewer, | viewer, | ||||
messageSelectionCriteria, | messageSelectionCriteria, | ||||
defaultNumberPerThread, | defaultNumberPerThread, | ||||
); | ); | ||||
const entryInfoPromise = fetchEntryInfos(viewer, [calendarQuery]); | const entryInfoPromise = fetchEntryInfos(viewer, [calendarQuery]); | ||||
const currentUserInfoPromise = fetchCurrentUserInfo(viewer); | const currentUserInfoPromise = fetchCurrentUserInfo(viewer); | ||||
const userInfoPromise = fetchKnownUserInfos(viewer); | const userStorePromise = (async () => { | ||||
await updateRelationshipsPromise; | |||||
const userInfos = await fetchKnownUserInfos(viewer); | |||||
return { userInfos, inconsistencyReports: [] }; | |||||
})(); | |||||
const sessionIDPromise = (async () => { | const sessionIDPromise = (async () => { | ||||
if (viewer.loggedIn) { | if (viewer.loggedIn) { | ||||
await setNewSession(viewer, calendarQuery, initialTime); | await setNewSession(viewer, calendarQuery, initialTime); | ||||
} | } | ||||
return viewer.sessionID; | return viewer.sessionID; | ||||
})(); | })(); | ||||
Show All 17 Lines | ): Promise<void> { | ||||
const entryStorePromise = (async () => { | const entryStorePromise = (async () => { | ||||
const { rawEntryInfos } = await entryInfoPromise; | const { rawEntryInfos } = await entryInfoPromise; | ||||
return { | return { | ||||
entryInfos: _keyBy('id')(rawEntryInfos), | entryInfos: _keyBy('id')(rawEntryInfos), | ||||
daysToEntries: daysToEntriesFromEntryInfos(rawEntryInfos), | daysToEntries: daysToEntriesFromEntryInfos(rawEntryInfos), | ||||
lastUserInteractionCalendar: initialTime, | lastUserInteractionCalendar: initialTime, | ||||
}; | }; | ||||
})(); | })(); | ||||
const userStorePromise = (async () => { | |||||
const userInfos = await userInfoPromise; | |||||
return { userInfos, inconsistencyReports: [] }; | |||||
})(); | |||||
const navInfoPromise = (async () => { | const navInfoPromise = (async () => { | ||||
const [ | const [ | ||||
{ threadInfos }, | { threadInfos }, | ||||
validUserIDs, | |||||
messageStore, | messageStore, | ||||
currentUserInfo, | currentUserInfo, | ||||
userStore, | userStore, | ||||
] = await Promise.all([ | ] = await Promise.all([ | ||||
threadInfoPromise, | threadInfoPromise, | ||||
validUserIDsPromise, | |||||
messageStorePromise, | messageStorePromise, | ||||
currentUserInfoPromise, | currentUserInfoPromise, | ||||
userStorePromise, | userStorePromise, | ||||
]); | ]); | ||||
const finalNavInfo = initialNavInfo; | const finalNavInfo = initialNavInfo; | ||||
finalNavInfo.selectedUserList = validUserIDs; | |||||
const requestedActiveChatThreadID = finalNavInfo.activeChatThreadID; | const requestedActiveChatThreadID = finalNavInfo.activeChatThreadID; | ||||
if ( | if ( | ||||
requestedActiveChatThreadID && | requestedActiveChatThreadID && | ||||
!threadIsPending(requestedActiveChatThreadID) && | !threadIsPending(requestedActiveChatThreadID) && | ||||
!threadHasPermission( | !threadHasPermission( | ||||
threadInfos[requestedActiveChatThreadID], | threadInfos[requestedActiveChatThreadID], | ||||
threadPermissions.VISIBLE, | threadPermissions.VISIBLE, | ||||
▲ Show 20 Lines • Show All 170 Lines • Show Last 20 Lines |