mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
114 lines
3.8 KiB
TypeScript
114 lines
3.8 KiB
TypeScript
import { UserInputError } from 'apollo-server'
|
|
import { getNeode } from '@db/neo4j'
|
|
import encryptPassword from '@helpers/encryptPassword'
|
|
import generateNonce from './helpers/generateNonce'
|
|
import existingEmailAddress from './helpers/existingEmailAddress'
|
|
import normalizeEmail from './helpers/normalizeEmail'
|
|
|
|
const neode = getNeode()
|
|
|
|
export default {
|
|
Mutation: {
|
|
Signup: async (_parent, args, context) => {
|
|
args.nonce = generateNonce()
|
|
args.email = normalizeEmail(args.email)
|
|
let emailAddress = await existingEmailAddress({ args, context })
|
|
/*
|
|
if (emailAddress.user) {
|
|
// what to do?
|
|
}
|
|
*/
|
|
if (emailAddress.alreadyExistingEmail) return emailAddress.alreadyExistingEmail
|
|
try {
|
|
emailAddress = await neode.create('EmailAddress', args)
|
|
return emailAddress.toJson()
|
|
} catch (e) {
|
|
throw new UserInputError(e.message)
|
|
}
|
|
},
|
|
SignupVerification: async (_parent, args, context) => {
|
|
const { termsAndConditionsAgreedVersion } = args
|
|
const regEx = /^[0-9]+\.[0-9]+\.[0-9]+$/g
|
|
if (!regEx.test(termsAndConditionsAgreedVersion)) {
|
|
throw new UserInputError('Invalid version format!')
|
|
}
|
|
args.termsAndConditionsAgreedAt = new Date().toISOString()
|
|
|
|
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(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
|
|
})
|
|
try {
|
|
const user = await writeTxResultPromise
|
|
return user
|
|
} catch (e) {
|
|
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
|
throw new UserInputError('User with this slug already exists!')
|
|
throw new UserInputError(e.message)
|
|
} finally {
|
|
session.close()
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
const signupCypher = (inviteCode) => {
|
|
let optionalMatch = ''
|
|
let optionalMerge = ''
|
|
if (inviteCode) {
|
|
optionalMatch = `
|
|
OPTIONAL MATCH
|
|
(inviteCode:InviteCode {code: $inviteCode})<-[:GENERATED]-(host:User)
|
|
`
|
|
optionalMerge = `
|
|
MERGE (user)-[:REDEEMED { createdAt: toString(datetime()) }]->(inviteCode)
|
|
MERGE (host)-[:INVITED { createdAt: toString(datetime()) }]->(user)
|
|
MERGE (user)-[:FOLLOWS { createdAt: toString(datetime()) }]->(host)
|
|
MERGE (host)-[:FOLLOWS { createdAt: toString(datetime()) }]->(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 user.sendNotificationEmails = true
|
|
SET email.verifiedAt = toString(datetime())
|
|
WITH user
|
|
OPTIONAL MATCH (post:Post)-[:IN]->(group:Group)
|
|
WHERE NOT group.groupType = 'public'
|
|
WITH user, collect(post) AS invisiblePosts
|
|
FOREACH (invisiblePost IN invisiblePosts |
|
|
MERGE (user)-[:CANNOT_SEE]->(invisiblePost)
|
|
)
|
|
RETURN user {.*}
|
|
`
|
|
return cypher
|
|
}
|