diff --git a/keyserver/src/responders/user-responders.js b/keyserver/src/responders/user-responders.js --- a/keyserver/src/responders/user-responders.js +++ b/keyserver/src/responders/user-responders.js @@ -11,6 +11,7 @@ baseLegalPolicies, policies, policyTypes, + type PolicyType, } from 'lib/facts/policies.js'; import { hasMinCodeVersion } from 'lib/shared/version-utils.js'; import type { @@ -268,7 +269,6 @@ +viewer: Viewer, +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest, +platformDetails: PlatformDetails, - +watchedIDs: $ReadOnlyArray, +userID: string, +calendarQuery: ?CalendarQuery, +socialProof?: ?SIWESocialProof, @@ -278,14 +278,23 @@ +shouldMarkPoliciesAsAcceptedAfterCookieCreation?: boolean, }; +type ProcessSuccessfulLoginResult = + | { + +success: true, + +newServerTime: number, + } + | { + +success: false, + +notAcknowledgedPolicies: $ReadOnlyArray, + }; + async function processSuccessfulLogin( params: ProcessSuccessfulLoginParams, -): Promise { +): Promise { const { viewer, deviceTokenUpdateRequest, platformDetails, - watchedIDs, userID, calendarQuery, socialProof, @@ -343,25 +352,13 @@ notAcknowledgedPolicies.length && hasMinCodeVersion(viewer.platformDetails, { native: 181 }) ) { - const currentUserInfo = await fetchLoggedInUserInfo(viewer); - return { - notAcknowledgedPolicies, - currentUserInfo: currentUserInfo, - rawMessageInfos: [], - truncationStatuses: {}, - userInfos: [], - rawEntryInfos: [], - serverTime: 0, - cookieChange: { - threadInfos: {}, - userInfos: [], - }, - }; + return { success: false, notAcknowledgedPolicies }; } if (calendarQuery) { await setNewSession(viewer, calendarQuery, newServerTime); } + const persistOlmNotifSessionPromise = (async () => { if (olmNotifSession && viewer.cookieID) { await persistFreshOlmSession( @@ -371,6 +368,7 @@ ); } })(); + // `pickledContentOlmSession` is created in `keyserverAuthResponder(...)` in // order to authenticate the user. Here, we simply persist the session if it // exists. @@ -384,6 +382,26 @@ } })(); + await Promise.all([ + persistOlmNotifSessionPromise, + persistOlmContentSessionPromise, + ]); + + return { success: true, newServerTime }; +} + +type FetchLoginResponseParams = { + +viewer: Viewer, + +watchedIDs: $ReadOnlyArray, + +calendarQuery: ?CalendarQuery, + +newServerTime: number, +}; + +async function fetchLoginResponse( + params: FetchLoginResponseParams, +): Promise { + const { viewer, watchedIDs, calendarQuery } = params; + const threadCursors: { [string]: null } = {}; for (const watchedThreadID of watchedIDs) { threadCursors[watchedThreadID] = null; @@ -409,8 +427,6 @@ entriesPromise, fetchKnownUserInfos(viewer), fetchLoggedInUserInfo(viewer), - persistOlmNotifSessionPromise, - persistOlmContentSessionPromise, ]); const rawEntryInfos = entriesResult ? entriesResult.rawEntryInfos : null; @@ -418,7 +434,7 @@ currentUserInfo, rawMessageInfos: messagesResult.rawMessageInfos, truncationStatuses: messagesResult.truncationStatuses, - serverTime: newServerTime, + serverTime: params.newServerTime, userInfos: values(userInfos), cookieChange: { threadInfos: threadsResult.threadInfos, @@ -434,6 +450,43 @@ return response; } +type HandleSuccessfulLoginResultParams = { + +viewer: Viewer, + +watchedIDs: $ReadOnlyArray, + +calendarQuery: ?CalendarQuery, +}; + +async function handleSuccessfulLoginResult( + result: ProcessSuccessfulLoginResult, + params: HandleSuccessfulLoginResultParams, +): Promise { + const { viewer, watchedIDs, calendarQuery } = params; + + if (!result.success) { + const currentUserInfo = await fetchLoggedInUserInfo(viewer); + return { + notAcknowledgedPolicies: result.notAcknowledgedPolicies, + currentUserInfo: currentUserInfo, + rawMessageInfos: [], + truncationStatuses: {}, + userInfos: [], + rawEntryInfos: [], + serverTime: 0, + cookieChange: { + threadInfos: {}, + userInfos: [], + }, + }; + } + + return await fetchLoginResponse({ + viewer, + watchedIDs, + calendarQuery, + newServerTime: result.newServerTime, + }); +} + export const logInRequestInputValidator: TInterface = tShape({ username: t.maybe(t.String), @@ -517,16 +570,20 @@ const id = userRow.id.toString(); - return await processSuccessfulLogin({ + const processSuccessfulLoginResult = await processSuccessfulLogin({ viewer, platformDetails: request.platformDetails, deviceTokenUpdateRequest: request.deviceTokenUpdateRequest, - watchedIDs: request.watchedIDs, userID: id, calendarQuery, signedIdentityKeysBlob, initialNotificationsEncryptedMessage, }); + return await handleSuccessfulLoginResult(processSuccessfulLoginResult, { + viewer, + watchedIDs: request.watchedIDs, + calendarQuery, + }); } export const siweAuthRequestInputValidator: TInterface = @@ -665,11 +722,10 @@ })(); // 10. Complete login with call to `processSuccessfulLogin(...)`. - const result = await processSuccessfulLogin({ + const processSuccessfulLoginResult = await processSuccessfulLogin({ viewer, platformDetails, deviceTokenUpdateRequest, - watchedIDs, userID, calendarQuery, socialProof, @@ -691,7 +747,12 @@ ); } - return result; + // 12. Fetch data from MariaDB for the response. + return await handleSuccessfulLoginResult(processSuccessfulLoginResult, { + viewer, + watchedIDs, + calendarQuery, + }); } export const keyserverAuthRequestInputValidator: TInterface = @@ -805,11 +866,10 @@ ]); // 5. Complete login with call to `processSuccessfulLogin(...)`. - const result = await processSuccessfulLogin({ + const processSuccessfulLoginResult = await processSuccessfulLogin({ viewer, platformDetails: request.platformDetails, deviceTokenUpdateRequest: request.deviceTokenUpdateRequest, - watchedIDs: request.watchedIDs, userID, calendarQuery, signedIdentityKeysBlob, @@ -824,7 +884,12 @@ await sendMessagesOnAccountCreation(viewer); } - return result; + // 7. Fetch data from MariaDB for the response. + return await handleSuccessfulLoginResult(processSuccessfulLoginResult, { + viewer, + watchedIDs: request.watchedIDs, + calendarQuery, + }); } export const updatePasswordRequestInputValidator: TInterface =