Changeset View
Changeset View
Standalone View
Standalone View
keyserver/src/responders/website-responders.js
Show All 38 Lines | |||||
import { | import { | ||||
currentUserInfoValidator, | currentUserInfoValidator, | ||||
userInfosValidator, | userInfosValidator, | ||||
} from 'lib/types/user-types.js'; | } from 'lib/types/user-types.js'; | ||||
import { currentDateInTimeZone } from 'lib/utils/date-utils.js'; | import { currentDateInTimeZone } from 'lib/utils/date-utils.js'; | ||||
import { ServerError } from 'lib/utils/errors.js'; | import { ServerError } from 'lib/utils/errors.js'; | ||||
import { promiseAll } from 'lib/utils/promises.js'; | import { promiseAll } from 'lib/utils/promises.js'; | ||||
import { defaultNotifPermissionAlertInfo } from 'lib/utils/push-alerts.js'; | import { defaultNotifPermissionAlertInfo } from 'lib/utils/push-alerts.js'; | ||||
import { infoFromURL } from 'lib/utils/url-utils.js'; | |||||
import { tBool, tNumber, tShape, tString } from 'lib/utils/validation-utils.js'; | import { tBool, tNumber, tShape, tString } from 'lib/utils/validation-utils.js'; | ||||
import getTitle from 'web/title/getTitle.js'; | import getTitle from 'web/title/getTitle.js'; | ||||
import { navInfoValidator } from 'web/types/nav-types.js'; | import { navInfoValidator } from 'web/types/nav-types.js'; | ||||
import { navInfoFromURL } from 'web/url-utils.js'; | import { navInfoFromURL } from 'web/url-utils.js'; | ||||
import { fetchEntryInfos } from '../fetchers/entry-fetchers.js'; | import { fetchEntryInfos } from '../fetchers/entry-fetchers.js'; | ||||
import { fetchMessageInfos } from '../fetchers/message-fetchers.js'; | import { fetchMessageInfos } from '../fetchers/message-fetchers.js'; | ||||
import { hasAnyNotAcknowledgedPolicies } from '../fetchers/policy-acknowledgment-fetchers.js'; | import { hasAnyNotAcknowledgedPolicies } from '../fetchers/policy-acknowledgment-fetchers.js'; | ||||
import { fetchThreadInfos } from '../fetchers/thread-fetchers.js'; | import { fetchThreadInfos } from '../fetchers/thread-fetchers.js'; | ||||
import { | import { | ||||
fetchCurrentUserInfo, | fetchCurrentUserInfo, | ||||
fetchKnownUserInfos, | fetchKnownUserInfos, | ||||
fetchUserInfos, | |||||
} from '../fetchers/user-fetchers.js'; | } from '../fetchers/user-fetchers.js'; | ||||
import { getWebPushConfig } from '../push/providers.js'; | import { getWebPushConfig } from '../push/providers.js'; | ||||
import { setNewSession } from '../session/cookies.js'; | import { setNewSession } from '../session/cookies.js'; | ||||
import { Viewer } from '../session/viewer.js'; | import { Viewer } from '../session/viewer.js'; | ||||
import { streamJSON, waitForStream } from '../utils/json-stream.js'; | import { streamJSON, waitForStream } from '../utils/json-stream.js'; | ||||
import { | import { | ||||
getAppURLFactsFromRequestURL, | getAppURLFactsFromRequestURL, | ||||
getCommAppURLFacts, | getCommAppURLFacts, | ||||
▲ Show 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | ): Promise<void> { | ||||
const baseHref = baseDomain + baseURL; | const baseHref = baseDomain + baseURL; | ||||
const loadingPromise = getWebpackCompiledRootComponentForSSR(); | const loadingPromise = getWebpackCompiledRootComponentForSSR(); | ||||
const hasNotAcknowledgedPoliciesPromise = hasAnyNotAcknowledgedPolicies( | const hasNotAcknowledgedPoliciesPromise = hasAnyNotAcknowledgedPolicies( | ||||
viewer.id, | viewer.id, | ||||
baseLegalPolicies, | baseLegalPolicies, | ||||
); | ); | ||||
let initialNavInfo; | const initialNavInfoPromise = (async () => { | ||||
try { | try { | ||||
initialNavInfo = navInfoFromURL(req.url, { | const urlInfo = infoFromURL(req.url); | ||||
let backupInfo = { | |||||
now: currentDateInTimeZone(viewer.timeZone), | now: currentDateInTimeZone(viewer.timeZone), | ||||
}); | }; | ||||
// Some user ids in selectedUserList might not exist in the userStore | |||||
// (e.g. they were included in the results of the user search endpoint) | |||||
// Because of that we keep their userInfos inside the navInfo. | |||||
if (urlInfo.selectedUserList) { | |||||
const fetchedUserInfos = await fetchUserInfos(urlInfo.selectedUserList); | |||||
const userInfos = {}; | |||||
for (const userID in fetchedUserInfos) { | |||||
const userInfo = fetchedUserInfos[userID]; | |||||
if (userInfo.username) { | |||||
userInfos[userID] = userInfo; | |||||
} | |||||
} | |||||
backupInfo = { userInfos, ...backupInfo }; | |||||
} | |||||
return navInfoFromURL(urlInfo, backupInfo); | |||||
} catch (e) { | } catch (e) { | ||||
throw new ServerError(e.message); | throw new ServerError(e.message); | ||||
} | } | ||||
})(); | |||||
const calendarQuery = { | const calendarQueryPromise = (async () => { | ||||
const initialNavInfo = await initialNavInfoPromise; | |||||
return { | |||||
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 = (async () => { | ||||
const calendarQuery = await calendarQueryPromise; | |||||
return await fetchEntryInfos(viewer, [calendarQuery]); | |||||
})(); | |||||
const currentUserInfoPromise = fetchCurrentUserInfo(viewer); | const currentUserInfoPromise = fetchCurrentUserInfo(viewer); | ||||
const userInfoPromise = fetchKnownUserInfos(viewer); | const userInfoPromise = fetchKnownUserInfos(viewer); | ||||
const sessionIDPromise = (async () => { | const sessionIDPromise = (async () => { | ||||
const calendarQuery = await calendarQueryPromise; | |||||
if (viewer.loggedIn) { | if (viewer.loggedIn) { | ||||
await setNewSession(viewer, calendarQuery, initialTime); | await setNewSession(viewer, calendarQuery, initialTime); | ||||
} | } | ||||
return viewer.sessionID; | return viewer.sessionID; | ||||
})(); | })(); | ||||
const threadStorePromise = (async () => { | const threadStorePromise = (async () => { | ||||
const [{ threadInfos }, hasNotAcknowledgedPolicies] = await Promise.all([ | const [{ threadInfos }, hasNotAcknowledgedPolicies] = await Promise.all([ | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | const userStorePromise = (async () => { | ||||
]); | ]); | ||||
return { | return { | ||||
userInfos: hasNotAcknowledgedPolicies ? {} : userInfos, | userInfos: hasNotAcknowledgedPolicies ? {} : userInfos, | ||||
inconsistencyReports: [], | inconsistencyReports: [], | ||||
}; | }; | ||||
})(); | })(); | ||||
const navInfoPromise = (async () => { | const navInfoPromise = (async () => { | ||||
const [{ threadInfos }, messageStore, currentUserInfo, userStore] = | const [ | ||||
await Promise.all([ | { threadInfos }, | ||||
messageStore, | |||||
currentUserInfo, | |||||
userStore, | |||||
finalNavInfo, | |||||
] = await Promise.all([ | |||||
threadInfoPromise, | threadInfoPromise, | ||||
messageStorePromise, | messageStorePromise, | ||||
currentUserInfoPromise, | currentUserInfoPromise, | ||||
userStorePromise, | userStorePromise, | ||||
initialNavInfoPromise, | |||||
]); | ]); | ||||
const finalNavInfo = initialNavInfo; | |||||
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 129 Lines • ▼ Show 20 Lines | const initialReduxState = await promiseAll({ | ||||
loadingStatuses: {}, | loadingStatuses: {}, | ||||
calendarFilters: defaultCalendarFilters, | calendarFilters: defaultCalendarFilters, | ||||
communityPickerStore: { chat: null, calendar: null }, | communityPickerStore: { chat: null, calendar: null }, | ||||
// We can use paths local to the <base href> on web | // We can use paths local to the <base href> on web | ||||
urlPrefix: '', | urlPrefix: '', | ||||
windowDimensions: { width: 0, height: 0 }, | windowDimensions: { width: 0, height: 0 }, | ||||
baseHref, | baseHref, | ||||
notifPermissionAlertInfo: defaultNotifPermissionAlertInfo, | notifPermissionAlertInfo: defaultNotifPermissionAlertInfo, | ||||
connection: { | connection: (async () => ({ | ||||
...defaultConnectionInfo(viewer.platform ?? 'web', viewer.timeZone), | ...defaultConnectionInfo(viewer.platform ?? 'web', viewer.timeZone), | ||||
actualizedCalendarQuery: calendarQuery, | actualizedCalendarQuery: await calendarQueryPromise, | ||||
}, | }))(), | ||||
watchedThreadIDs: [], | watchedThreadIDs: [], | ||||
lifecycleState: 'active', | lifecycleState: 'active', | ||||
enabledApps: defaultWebEnabledApps, | enabledApps: defaultWebEnabledApps, | ||||
reportStore: { | reportStore: { | ||||
enabledReports: defaultEnabledReports, | enabledReports: defaultEnabledReports, | ||||
queuedReports: [], | queuedReports: [], | ||||
}, | }, | ||||
nextLocalID: 0, | nextLocalID: 0, | ||||
▲ Show 20 Lines • Show All 227 Lines • Show Last 20 Lines |