diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js --- a/keyserver/src/creators/account-creator.js +++ b/keyserver/src/creators/account-creator.js @@ -14,15 +14,8 @@ import type { UserDetail, ReservedUsernameMessage, - SignedIdentityKeysBlob, } from 'lib/types/crypto-types.js'; -import type { - PlatformDetails, - DeviceTokenUpdateRequest, -} from 'lib/types/device-types.js'; -import type { CalendarQuery } from 'lib/types/entry-types.js'; import { messageTypes } from 'lib/types/message-types-enum.js'; -import type { SIWESocialProof } from 'lib/types/siwe-types.js'; import { threadTypes } from 'lib/types/thread-types-enum.js'; import { ServerError } from 'lib/utils/errors.js'; import { values } from 'lib/utils/objects.js'; @@ -222,57 +215,6 @@ }; } -export type ProcessSIWEAccountCreationRequest = { - +address: string, - +calendarQuery: CalendarQuery, - +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest, - +platformDetails: PlatformDetails, - +socialProof: SIWESocialProof, - +signedIdentityKeysBlob?: ?SignedIdentityKeysBlob, -}; -// Note: `processSIWEAccountCreation(...)` assumes that the validity of -// `ProcessSIWEAccountCreationRequest` was checked at call site. -async function processSIWEAccountCreation( - viewer: Viewer, - request: ProcessSIWEAccountCreationRequest, -): Promise { - const { calendarQuery, signedIdentityKeysBlob } = request; - await verifyCalendarQueryThreadIDs(calendarQuery); - - const time = Date.now(); - const deviceToken = request.deviceTokenUpdateRequest - ? request.deviceTokenUpdateRequest.deviceToken - : viewer.deviceToken; - const [id] = await createIDs('users', 1); - const newUserRow = [id, request.address, request.address, time]; - const newUserQuery = SQL` - INSERT INTO users(id, username, ethereum_address, creation_time) - VALUES ${[newUserRow]} - `; - const [userViewerData] = await Promise.all([ - createNewUserCookie(id, { - platformDetails: request.platformDetails, - deviceToken, - socialProof: request.socialProof, - signedIdentityKeysBlob, - }), - deleteCookie(viewer.cookieID), - dbQuery(newUserQuery), - ]); - viewer.setNewCookie(userViewerData); - - await setNewSession(viewer, calendarQuery, 0); - await processAccountCreationCommon(viewer); - - ignorePromiseRejections( - createAndSendReservedUsernameMessage([ - { username: request.address, userID: id }, - ]), - ); - - return id; -} - async function processAccountCreationCommon(viewer: Viewer) { const admin = await thisKeyserverAdmin(); @@ -340,6 +282,6 @@ export { createAccount, - processSIWEAccountCreation, processAccountCreationCommon, + createAndSendReservedUsernameMessage, }; 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 @@ -82,6 +82,7 @@ } from 'lib/utils/crypto-utils.js'; import { ServerError } from 'lib/utils/errors.js'; import { values } from 'lib/utils/objects.js'; +import { ignorePromiseRejections } from 'lib/utils/promises.js'; import { getPublicKeyFromSIWEStatement, isValidSIWEMessage, @@ -105,10 +106,11 @@ verifyCalendarQueryThreadIDs, } from './entry-responders.js'; import { + createAndSendReservedUsernameMessage, processAccountCreationCommon, createAccount, - processSIWEAccountCreation, } from '../creators/account-creator.js'; +import createIDs from '../creators/id-creator.js'; import { createOlmSession, persistFreshOlmSession, @@ -602,6 +604,7 @@ signedIdentityKeysBlob, initialNotificationsEncryptedMessage, doNotRegister, + watchedIDs, } = request; const calendarQuery = normalizeCalendarQuery(request.calendarQuery); @@ -612,9 +615,11 @@ } // 2. Check if there's already a user for this ETH address. - const existingUserID = await fetchUserIDForEthereumAddress( - siweMessage.address, - ); + // Verify calendarQuery. + const [existingUserID] = await Promise.all([ + fetchUserIDForEthereumAddress(siweMessage.address), + verifyCalendarQueryThreadIDs(calendarQuery), + ]); if (!existingUserID && doNotRegister) { throw new ServerError('account_does_not_exist'); } @@ -692,29 +697,29 @@ siweMessageSignature: signature, }; - // 9. Create account with call to `processSIWEAccountCreation(...)` - // if address does not correspond to an existing user. - let userID = existingUserID; - if (!userID) { - const siweAccountCreationRequest = { - address: siweMessage.address, - calendarQuery, - deviceTokenUpdateRequest, - platformDetails, - socialProof, - }; - userID = await processSIWEAccountCreation( - viewer, - siweAccountCreationRequest, - ); - } + // 9. Create account if address does not correspond to an existing user. + const userID = await (async () => { + if (existingUserID) { + return existingUserID; + } + const time = Date.now(); + const [id] = await createIDs('users', 1); + const newUserRow = [id, siweMessage.address, siweMessage.address, time]; + const newUserQuery = SQL` + INSERT INTO users(id, username, ethereum_address, creation_time) + VALUES ${[newUserRow]} + `; + + await dbQuery(newUserQuery); + return id; + })(); // 10. Complete login with call to `processSuccessfulLogin(...)`. - return await processSuccessfulLogin({ + const result = await processSuccessfulLogin({ viewer, - platformDetails: request.platformDetails, - deviceTokenUpdateRequest: request.deviceTokenUpdateRequest, - watchedIDs: request.watchedIDs, + platformDetails, + deviceTokenUpdateRequest, + watchedIDs, userID, calendarQuery, socialProof, @@ -722,6 +727,21 @@ initialNotificationsEncryptedMessage, shouldMarkPoliciesAsAcceptedAfterCookieCreation: !existingUserID, }); + + // 11. Create threads with call to `processAccountCreationCommon(...)`, + // if the account has just been registered. Also, set the username as + // reserved. + if (!existingUserID) { + await processAccountCreationCommon(viewer); + + ignorePromiseRejections( + createAndSendReservedUsernameMessage([ + { username: siweMessage.address, userID }, + ]), + ); + } + + return result; } export const keyserverAuthRequestInputValidator: TInterface =