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 @@ -11,6 +11,7 @@ import type { RegisterResponse, RegisterRequest, + UserIdentifier, } from 'lib/types/account-types.js'; import type { ReservedUsernameMessage, @@ -305,4 +306,107 @@ return id; } -export { createAccount, processSIWEAccountCreation }; +export type ProcessVerifiedIdentityAccountCreationRequest = { + +identifier: UserIdentifier, + +calendarQuery: CalendarQuery, + +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest, + +platformDetails: PlatformDetails, + +socialProof?: ?SIWESocialProof, + +userID: string, +}; +// Note: `processVerifiedIdentityAccountCreation(...)` assumes that the validity +// of `ProcessVerifiedIdentityAccountCreationRequest` was checked at call site. +async function processVerifiedIdentityAccountCreation( + viewer: Viewer, + request: ProcessVerifiedIdentityAccountCreationRequest, +): Promise { + const { calendarQuery, userID, identifier } = request; + await verifyCalendarQueryThreadIDs(calendarQuery); + + const time = Date.now(); + const deviceToken = request.deviceTokenUpdateRequest + ? request.deviceTokenUpdateRequest.deviceToken + : viewer.deviceToken; + + let username, ethereum_address; + + if ('username' in identifier) { + username = identifier.username; + } + + if ('walletAddress' in identifier) { + ethereum_address = identifier.walletAddress; + if (!username) { + username = identifier.walletAddress; + } + } + + const newUserRow = [userID, username, ethereum_address, time]; + const newUserQuery = SQL` + INSERT INTO users(id, username, ethereum_address, creation_time) + VALUES ${[newUserRow]} + `; + const [userViewerData] = await Promise.all([ + createNewUserCookie(userID, { + platformDetails: request.platformDetails, + deviceToken, + socialProof: request.socialProof, + }), + deleteCookie(viewer.cookieID), + dbQuery(newUserQuery), + ]); + viewer.setNewCookie(userViewerData); + + await setNewSession(viewer, calendarQuery, 0); + + await Promise.all([ + updateThread( + createScriptViewer(ashoat.id), + { + threadID: genesis.id, + changes: { newMemberIDs: [userID] }, + }, + { forceAddMembers: true, silenceMessages: true, ignorePermissions: true }, + ), + viewerAcknowledgmentUpdater(viewer, policyTypes.tosAndPrivacyPolicy), + ]); + + const [privateThreadResult, ashoatThreadResult] = await Promise.all([ + createPrivateThread(viewer), + createThread( + viewer, + { + type: threadTypes.PERSONAL, + initialMemberIDs: [ashoat.id], + }, + { forceAddMembers: true }, + ), + ]); + const ashoatThreadID = ashoatThreadResult.newThreadID; + const privateThreadID = privateThreadResult.newThreadID; + + let messageTime = Date.now(); + const ashoatMessageDatas = ashoatMessages.map(message => ({ + type: messageTypes.TEXT, + threadID: ashoatThreadID, + creatorID: ashoat.id, + time: messageTime++, + text: message, + })); + const privateMessageDatas = privateMessages.map(message => ({ + type: messageTypes.TEXT, + threadID: privateThreadID, + creatorID: commbot.userID, + time: messageTime++, + text: message, + })); + const messageDatas = [...ashoatMessageDatas, ...privateMessageDatas]; + await Promise.all([createMessages(viewer, messageDatas)]); + return userID; +} + +export { + createAccount, + processSIWEAccountCreation, + processVerifiedIdentityAccountCreation, +}; diff --git a/lib/types/account-types.js b/lib/types/account-types.js --- a/lib/types/account-types.js +++ b/lib/types/account-types.js @@ -159,6 +159,10 @@ +notAcknowledgedPolicies?: $ReadOnlyArray, }; +export type UserIdentifier = + | { username: string, userID: string } + | { walletAddress: string, userID: string }; + export type UpdatePasswordRequest = { code: string, password: string,