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 @@ -24,6 +24,7 @@ notificationTypeValues, logInActionSources, } from 'lib/types/account-types'; +import type { CalendarQuery } from 'lib/types/entry-types.js'; import { defaultNumberPerThread } from 'lib/types/message-types'; import type { SIWEAuthRequest, SIWEMessage } from 'lib/types/siwe-types.js'; import type { @@ -189,66 +190,19 @@ return await createAccount(viewer, request); } -const logInRequestInputValidator = tShape({ - username: t.maybe(t.String), - usernameOrEmail: t.maybe(t.union([tEmail, tOldValidUsername])), - password: tPassword, - watchedIDs: t.list(t.String), - calendarQuery: t.maybe(entryQueryInputValidator), - deviceTokenUpdateRequest: t.maybe(deviceTokenUpdateRequestInputValidator), - platformDetails: tPlatformDetails, - source: t.maybe(t.enums.of(values(logInActionSources))), -}); - -async function logInResponder( +async function processSuccessfulLogin( viewer: Viewer, input: any, -): Promise { - await validateInput(viewer, logInRequestInputValidator, input); + userID: string, + calendarQuery: ?CalendarQuery, +) { const request: LogInRequest = input; - - const calendarQuery = request.calendarQuery - ? normalizeCalendarQuery(request.calendarQuery) - : null; - const promises = {}; - if (calendarQuery) { - promises.verifyCalendarQueryThreadIDs = verifyCalendarQueryThreadIDs( - calendarQuery, - ); - } - const username = request.username ?? request.usernameOrEmail; - if (!username) { - throw new ServerError('invalid_parameters'); - } - const userQuery = SQL` - SELECT id, hash, username - FROM users - WHERE LCASE(username) = LCASE(${username}) - `; - promises.userQuery = dbQuery(userQuery); - const { - userQuery: [userResult], - } = await promiseAll(promises); - - if (userResult.length === 0) { - throw new ServerError('invalid_parameters'); - } - const userRow = userResult[0]; - if (!userRow.hash || !bcrypt.compareSync(request.password, userRow.hash)) { - if (hasMinCodeVersion(viewer.platformDetails, 99999)) { - throw new ServerError('invalid_parameters'); - } else { - throw new ServerError('invalid_credentials'); - } - } - const id = userRow.id.toString(); - const newServerTime = Date.now(); const deviceToken = request.deviceTokenUpdateRequest ? request.deviceTokenUpdateRequest.deviceToken : viewer.deviceToken; const [userViewerData] = await Promise.all([ - createNewUserCookie(id, { + createNewUserCookie(userID, { platformDetails: request.platformDetails, deviceToken, }), @@ -297,6 +251,62 @@ return response; } +const logInRequestInputValidator = tShape({ + username: t.maybe(t.String), + usernameOrEmail: t.maybe(t.union([tEmail, tOldValidUsername])), + password: tPassword, + watchedIDs: t.list(t.String), + calendarQuery: t.maybe(entryQueryInputValidator), + deviceTokenUpdateRequest: t.maybe(deviceTokenUpdateRequestInputValidator), + platformDetails: tPlatformDetails, + source: t.maybe(t.enums.of(values(logInActionSources))), +}); + +async function logInResponder( + viewer: Viewer, + input: any, +): Promise { + await validateInput(viewer, logInRequestInputValidator, input); + const request: LogInRequest = input; + + const calendarQuery = request.calendarQuery + ? normalizeCalendarQuery(request.calendarQuery) + : null; + const promises = {}; + if (calendarQuery) { + promises.verifyCalendarQueryThreadIDs = verifyCalendarQueryThreadIDs( + calendarQuery, + ); + } + const username = request.username ?? request.usernameOrEmail; + if (!username) { + throw new ServerError('invalid_parameters'); + } + const userQuery = SQL` + SELECT id, hash, username + FROM users + WHERE LCASE(username) = LCASE(${username}) + `; + promises.userQuery = dbQuery(userQuery); + const { + userQuery: [userResult], + } = await promiseAll(promises); + + if (userResult.length === 0) { + throw new ServerError('invalid_parameters'); + } + const userRow = userResult[0]; + if (!userRow.hash || !bcrypt.compareSync(request.password, userRow.hash)) { + if (hasMinCodeVersion(viewer.platformDetails, 99999)) { + throw new ServerError('invalid_parameters'); + } else { + throw new ServerError('invalid_credentials'); + } + } + const id = userRow.id.toString(); + return await processSuccessfulLogin(viewer, input, id, calendarQuery); +} + const siweAuthRequestInputValidator = tShape({ signature: t.String, message: t.String,