mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
further invite code
This commit is contained in:
parent
bcbc933657
commit
a1967815bf
@ -149,6 +149,7 @@ export default shield(
|
||||
pinPost: isAdmin,
|
||||
unpinPost: isAdmin,
|
||||
UpdateDonations: isAdmin,
|
||||
CreateInviteCode: isAuthenticated,
|
||||
},
|
||||
User: {
|
||||
email: or(isMyOwn, isAdmin),
|
||||
|
||||
19
backend/src/models/InviteCode.js
Normal file
19
backend/src/models/InviteCode.js
Normal file
@ -0,0 +1,19 @@
|
||||
export default {
|
||||
code: { type: 'string', primary: true },
|
||||
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
|
||||
uses: { type: 'int', default: () => 0 },
|
||||
maxUses: { type: 'int', default: () => 1 },
|
||||
active: { type: 'boolean', default: () => true },
|
||||
createdBy: {
|
||||
type: 'relationship',
|
||||
relationship: 'CREATED',
|
||||
target: 'User',
|
||||
direction: 'in',
|
||||
},
|
||||
usedBy: {
|
||||
type: 'relationship',
|
||||
relationship: 'USED',
|
||||
target: 'User',
|
||||
direction: 'in',
|
||||
},
|
||||
}
|
||||
@ -100,6 +100,18 @@ export default {
|
||||
target: 'User',
|
||||
direction: 'in',
|
||||
},
|
||||
createdInvite: {
|
||||
type: 'relationship',
|
||||
relationship: 'CREATED',
|
||||
target: 'InviteCode',
|
||||
direction: 'out',
|
||||
},
|
||||
usedInvite: {
|
||||
type: 'relationship',
|
||||
relationship: 'USED',
|
||||
target: 'InviteCode',
|
||||
direction: 'out',
|
||||
},
|
||||
termsAndConditionsAgreedVersion: {
|
||||
type: 'string',
|
||||
allow: [null],
|
||||
|
||||
@ -15,4 +15,5 @@ export default {
|
||||
Donations: require('./Donations.js').default,
|
||||
Report: require('./Report.js').default,
|
||||
Migration: require('./Migration.js').default,
|
||||
InviteCode: require('./InviteCode.js').default,
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
export default function generateInviteCode() {
|
||||
return Array.from({length: 6}, (n = Math.floor(Math.random() * 36)) => {
|
||||
return String.fromCharCode(n > 9 ? n + 55 : n + 48)
|
||||
}).join('')
|
||||
}
|
||||
66
backend/src/schema/resolvers/inviteCodes.js
Normal file
66
backend/src/schema/resolvers/inviteCodes.js
Normal file
@ -0,0 +1,66 @@
|
||||
import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||
import generateInvieCode from './helpers/generateInviteCode'
|
||||
import Resolver from './helpers/Resolver'
|
||||
|
||||
const uniqueInviteCode = async (session, code) => {
|
||||
return session.readTransaction(async (txc) => {
|
||||
const result = await txc.run(
|
||||
`MATCH (ic:InviteCode { id: $code }) RETURN count(ic) AS count`,
|
||||
{ code },
|
||||
)
|
||||
return parseInt(String(result.records[0].get('count'))) === 0
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
CreateInviteCode: async (_parent, args, context, _resolveInfo) => {
|
||||
const {
|
||||
user: { id: userId },
|
||||
} = context
|
||||
const session = context.driver.session()
|
||||
let code = generateInvieCode()
|
||||
let response
|
||||
while(!await uniqueInviteCode(session, code)) {
|
||||
code = generateInvieCode()
|
||||
}
|
||||
const writeTxResultPromise = session.writeTransaction(async (txc) => {
|
||||
const result = await txc.run(
|
||||
`MATCH (user:User {id: $userId})
|
||||
MERGE (user)-[:CREATED]->(ic:InviteCode {
|
||||
code: $code,
|
||||
createdAt: toString(datetime()),
|
||||
uses: $uses,
|
||||
maxUses: $maxUses,
|
||||
active: true
|
||||
}) RETURN ic AS inviteCode`,
|
||||
{
|
||||
userId,
|
||||
code,
|
||||
maxUses: args.maxUses,
|
||||
uses: 0,
|
||||
},
|
||||
)
|
||||
return result.records.map((record) => record.get('inviteCode').properties)
|
||||
})
|
||||
try {
|
||||
const txResult = await writeTxResultPromise
|
||||
console.log(txResult)
|
||||
response = txResult[0]
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
return response
|
||||
}
|
||||
},
|
||||
InviteCode: {
|
||||
...Resolver('InviteCode', {
|
||||
hasOne: {
|
||||
createdBy: '<-[:CREATED]-(related:User)',
|
||||
},
|
||||
hasMany: {
|
||||
usedBy: '<-[:USED]-(related:User)',
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
@ -293,6 +293,7 @@ export default {
|
||||
avatar: '-[:AVATAR_IMAGE]->(related:Image)',
|
||||
invitedBy: '<-[:INVITED]-(related:User)',
|
||||
location: '-[:IS_IN]->(related:Location)',
|
||||
usedInviteCode: '-[:USED]->(related:InviteCode)',
|
||||
},
|
||||
hasMany: {
|
||||
followedBy: '<-[:FOLLOWS]-(related:User)',
|
||||
@ -304,6 +305,7 @@ export default {
|
||||
shouted: '-[:SHOUTED]->(related:Post)',
|
||||
categories: '-[:CATEGORIZED]->(related:Category)',
|
||||
badges: '<-[:REWARDED]-(related:Badge)',
|
||||
inviteCodes: '-[:CREATED]->(related:InviteCode)',
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
14
backend/src/schema/types/type/InviteCode.gql
Normal file
14
backend/src/schema/types/type/InviteCode.gql
Normal file
@ -0,0 +1,14 @@
|
||||
type InviteCode {
|
||||
code: ID!
|
||||
createdAt: String
|
||||
uses: Int!
|
||||
maxUses: Int!
|
||||
createdBy: User @relation(name: "CREATED", direction: "IN")
|
||||
usedBy: [User] @relation(name: "USED", direction: "IN")
|
||||
active: Boolean!
|
||||
}
|
||||
|
||||
|
||||
type Mutation {
|
||||
CreateInviteCode(maxUses: Int = 1): InviteCode
|
||||
}
|
||||
@ -56,6 +56,9 @@ type User {
|
||||
followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN")
|
||||
followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(DISTINCT r)")
|
||||
|
||||
inviteCodes: [InviteCode] @relation(name: "CREATED", direction: "OUT")
|
||||
usedInviteCode: InviteCode @relation(name: "USED", direction: "OUT")
|
||||
|
||||
# Is the currently logged in user following that user?
|
||||
followedByCurrentUser: Boolean! @cypher(
|
||||
statement: """
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user