diff --git a/backend/src/schema/resolvers/registration.js b/backend/src/schema/resolvers/registration.js index f1c43be21..075f65554 100644 --- a/backend/src/schema/resolvers/registration.js +++ b/backend/src/schema/resolvers/registration.js @@ -29,34 +29,22 @@ export default { } args.termsAndConditionsAgreedAt = new Date().toISOString() - let { nonce, email } = args + let { nonce, email, inviteCode } = args email = normalizeEmail(email) delete args.nonce delete args.email + delete args.inviteCode args = encryptPassword(args) const { driver } = context const session = driver.session() const writeTxResultPromise = session.writeTransaction(async (transaction) => { - const createUserTransactionResponse = await transaction.run( - ` - MATCH(email:EmailAddress {nonce: $nonce, email: $email}) - WHERE NOT (email)-[:BELONGS_TO]->() - CREATE (user:User) - MERGE(user)-[:PRIMARY_EMAIL]->(email) - MERGE(user)<-[:BELONGS_TO]-(email) - SET user += $args - SET user.id = randomUUID() - SET user.role = 'user' - SET user.createdAt = toString(datetime()) - SET user.updatedAt = toString(datetime()) - SET user.allowEmbedIframes = FALSE - SET user.showShoutsPublicly = FALSE - SET email.verifiedAt = toString(datetime()) - RETURN user {.*} - `, - { args, nonce, email }, - ) + const createUserTransactionResponse = await transaction.run(signupCypher(inviteCode), { + args, + nonce, + email, + inviteCode, + }) const [user] = createUserTransactionResponse.records.map((record) => record.get('user')) if (!user) throw new UserInputError('Invalid email or nonce') return user @@ -74,3 +62,39 @@ export default { }, }, } + +const signupCypher = (inviteCode) => { + let optionalMatch = '' + let optionalMerge = '' + if (inviteCode) { + optionalMatch = ` + OPTIONAL MATCH + (inviteCode:InviteCode {code: $inviteCode})<-[:GENERATED]-(host:User) + ` + optionalMerge = ` + MERGE(user)-[:REDEEMED]->(inviteCode) + MERGE(host)-[:INVITED]->(user) + MERGE(user)-[:FOLLOWS]->(host) + MERGE(host)-[:FOLLOWS]->(user) + ` + } + const cypher = ` + MATCH(email:EmailAddress {nonce: $nonce, email: $email}) + WHERE NOT (email)-[:BELONGS_TO]->() + ${optionalMatch} + CREATE (user:User) + MERGE(user)-[:PRIMARY_EMAIL]->(email) + MERGE(user)<-[:BELONGS_TO]-(email) + ${optionalMerge} + SET user += $args + SET user.id = randomUUID() + SET user.role = 'user' + SET user.createdAt = toString(datetime()) + SET user.updatedAt = toString(datetime()) + SET user.allowEmbedIframes = FALSE + SET user.showShoutsPublicly = FALSE + SET email.verifiedAt = toString(datetime()) + RETURN user {.*} + ` + return cypher +} diff --git a/backend/src/schema/types/type/EmailAddress.gql b/backend/src/schema/types/type/EmailAddress.gql index ef9de9e47..b2e65eafa 100644 --- a/backend/src/schema/types/type/EmailAddress.gql +++ b/backend/src/schema/types/type/EmailAddress.gql @@ -13,7 +13,7 @@ type Mutation { SignupVerification( nonce: String! email: String! - inviteCode: String + inviteCode: String = null name: String! password: String! slug: String