Added submission list filter based on authentificated user. Sorted object parameters and imports
This commit is contained in:
parent
a07e0d752f
commit
4f82c80922
@ -1,17 +1,16 @@
|
|||||||
import { PrismaClient } from '@prisma/client'
|
import jwt from 'jsonwebtoken'
|
||||||
import {
|
import {
|
||||||
ApolloError,
|
ApolloError,
|
||||||
AuthenticationError,
|
AuthenticationError,
|
||||||
ForbiddenError
|
ForbiddenError
|
||||||
} from 'apollo-server-express'
|
} from 'apollo-server-express'
|
||||||
import jwt from 'jsonwebtoken'
|
import { CheckRightsAndResolve } from './types'
|
||||||
|
import { getDBFormAuthor } from '../db'
|
||||||
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
import { sendToken } from '../mailer'
|
||||||
|
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
import { getDBFormAuthor } from '../db'
|
|
||||||
import { sendToken } from '../mailer'
|
|
||||||
import { CheckRightsAndResolve } from './types'
|
|
||||||
|
|
||||||
const checkRightsAndResolve: CheckRightsAndResolve = async (params) => {
|
const checkRightsAndResolve: CheckRightsAndResolve = async (params) => {
|
||||||
const { user, expected, controller } = params
|
const { user, expected, controller } = params
|
||||||
|
|
||||||
@ -36,8 +35,8 @@ const getFormAuthor = async (db: PrismaClient, id: number) => {
|
|||||||
|
|
||||||
const tokenGenerate = (email: string, id: number) => {
|
const tokenGenerate = (email: string, id: number) => {
|
||||||
return jwt.sign({ email, id }, '' + process.env.JWT_SECRET, {
|
return jwt.sign({ email, id }, '' + process.env.JWT_SECRET, {
|
||||||
expiresIn: '7 days',
|
algorithm: 'HS256',
|
||||||
algorithm: 'HS256'
|
expiresIn: '7 days'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,4 +51,4 @@ const sendTokenEmail = async (
|
|||||||
if (res[0].statusCode != 202) return new ApolloError("Couldn't send email")
|
if (res[0].statusCode != 202) return new ApolloError("Couldn't send email")
|
||||||
}
|
}
|
||||||
|
|
||||||
export { checkRightsAndResolve, getFormAuthor, tokenGenerate, sendTokenEmail }
|
export { checkRightsAndResolve, getFormAuthor, sendTokenEmail, tokenGenerate }
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { PrismaClient, Answer } from '@prisma/client'
|
import { Answer, PrismaClient } from '@prisma/client'
|
||||||
import { ApolloError } from 'apollo-server-express'
|
import { ApolloError } from 'apollo-server-express'
|
||||||
|
|
||||||
import { createDBForm, getDBForm, getDBFormByUser, submitDBAnswer } from '../db'
|
|
||||||
import { FullForm } from '../db/types'
|
|
||||||
import {
|
import {
|
||||||
ChoisesQuestion,
|
ChoisesQuestion,
|
||||||
Form as GraphqlForm,
|
Form as GraphqlForm,
|
||||||
@ -12,44 +9,55 @@ import {
|
|||||||
MutationFormSubmitArgs,
|
MutationFormSubmitArgs,
|
||||||
Question
|
Question
|
||||||
} from '../typeDefs/typeDefs.gen'
|
} from '../typeDefs/typeDefs.gen'
|
||||||
|
|
||||||
import { createChoises, newForm } from './types'
|
import { createChoises, newForm } from './types'
|
||||||
|
import {
|
||||||
|
createDBForm,
|
||||||
|
getDBForm,
|
||||||
|
getDBFormsByUser,
|
||||||
|
submitDBAnswer
|
||||||
|
} from '../db'
|
||||||
|
|
||||||
const getForm = async (db: PrismaClient, id: number) => {
|
const getForm = async (
|
||||||
const dbForm: FullForm = await getDBForm(db, id)
|
db: PrismaClient,
|
||||||
|
id: number,
|
||||||
|
user: { requesterId: number; userId: number }
|
||||||
|
) => {
|
||||||
|
const dbForm = await getDBForm(db, id, user)
|
||||||
|
|
||||||
if (dbForm == null) throw new ApolloError('Not found')
|
if (dbForm == null) throw new ApolloError('Not found')
|
||||||
|
|
||||||
const form: GraphqlForm = {
|
const form: GraphqlForm = {
|
||||||
id: dbForm.id,
|
author: dbForm.author,
|
||||||
title: dbForm.title,
|
|
||||||
questions: [...dbForm.choisesQuestions, ...dbForm.inputQuestions],
|
|
||||||
dateCreated: dbForm.dateCreated.toString(),
|
dateCreated: dbForm.dateCreated.toString(),
|
||||||
submissions: dbForm.submissions.map<FormSubmission>((submission) => ({
|
id: dbForm.id,
|
||||||
|
questions: [...dbForm.choisesQuestions, ...dbForm.inputQuestions],
|
||||||
|
submissions: user.requesterId
|
||||||
|
? dbForm.submissions.map((submission) => ({
|
||||||
answers: submission.answers,
|
answers: submission.answers,
|
||||||
date: submission.date.toString(),
|
date: submission.date.toString(),
|
||||||
id: submission.id
|
id: submission.id
|
||||||
})),
|
}))
|
||||||
author: dbForm.author
|
: undefined,
|
||||||
|
title: dbForm.title
|
||||||
}
|
}
|
||||||
|
|
||||||
return form
|
return form
|
||||||
}
|
}
|
||||||
|
|
||||||
const getForms = async (db: PrismaClient, userId: number) => {
|
const getForms = async (db: PrismaClient, userId: number) => {
|
||||||
const dbForms = await getDBFormByUser(db, userId)
|
const dbForms = await getDBFormsByUser(db, userId)
|
||||||
|
|
||||||
const forms = [
|
const forms = [
|
||||||
...dbForms.map((form) => ({
|
...dbForms.map((form) => ({
|
||||||
id: form.id,
|
|
||||||
title: form.title,
|
|
||||||
questions: [...form.choisesQuestions, ...form.inputQuestions],
|
|
||||||
dateCreated: form.dateCreated.toString(),
|
dateCreated: form.dateCreated.toString(),
|
||||||
|
id: form.id,
|
||||||
|
questions: [...form.choisesQuestions, ...form.inputQuestions],
|
||||||
submissions: form.submissions.map<FormSubmission>((submission) => ({
|
submissions: form.submissions.map<FormSubmission>((submission) => ({
|
||||||
answers: submission.answers,
|
answers: submission.answers,
|
||||||
date: submission.date.toString(),
|
date: submission.date.toString(),
|
||||||
id: submission.id
|
id: submission.id
|
||||||
}))
|
})),
|
||||||
|
title: form.title
|
||||||
}))
|
}))
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -63,7 +71,28 @@ const createFormFrom = async (
|
|||||||
) => {
|
) => {
|
||||||
const parsedQuestions = <Question[]>JSON.parse(params.questions)
|
const parsedQuestions = <Question[]>JSON.parse(params.questions)
|
||||||
const newForm: newForm = {
|
const newForm: newForm = {
|
||||||
title: params.title,
|
choisesQuestions: {
|
||||||
|
create: parsedQuestions.flatMap<createChoises>(
|
||||||
|
(val: InputQuestion | ChoisesQuestion, index) => {
|
||||||
|
if ('type' in val) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
number: index,
|
||||||
|
title: val.title,
|
||||||
|
type: val.type,
|
||||||
|
variants: {
|
||||||
|
create: val.variants
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
inputQuestions: {
|
inputQuestions: {
|
||||||
create: parsedQuestions.filter(
|
create: parsedQuestions.filter(
|
||||||
(val: InputQuestion | ChoisesQuestion, index) => {
|
(val: InputQuestion | ChoisesQuestion, index) => {
|
||||||
@ -75,25 +104,7 @@ const createFormFrom = async (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
choisesQuestions: {
|
title: params.title
|
||||||
create: parsedQuestions.flatMap<createChoises>(
|
|
||||||
(val: InputQuestion | ChoisesQuestion, index) => {
|
|
||||||
if ('type' in val) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
number: index,
|
|
||||||
title: val.title,
|
|
||||||
type: val.type,
|
|
||||||
variants: { create: val.variants }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return createDBForm(db, newForm, id)
|
return createDBForm(db, newForm, id)
|
||||||
@ -109,4 +120,4 @@ const submitAnswer = async (
|
|||||||
return submitDBAnswer(db, userId, formId, parsedAnswers)
|
return submitDBAnswer(db, userId, formId, parsedAnswers)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getForm, getForms, createFormFrom, submitAnswer }
|
export { createFormFrom, getForm, getForms, submitAnswer }
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { getForm, getForms, createFormFrom } from './form'
|
|
||||||
import { checkRightsAndResolve, getFormAuthor, sendTokenEmail } from './auth'
|
import { checkRightsAndResolve, getFormAuthor, sendTokenEmail } from './auth'
|
||||||
|
import { createFormFrom, getForm, getForms, submitAnswer } from './form'
|
||||||
import { findUserBy } from './user'
|
import { findUserBy } from './user'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
checkRightsAndResolve,
|
checkRightsAndResolve,
|
||||||
|
createFormFrom,
|
||||||
|
findUserBy,
|
||||||
getForm,
|
getForm,
|
||||||
getFormAuthor,
|
getFormAuthor,
|
||||||
getForms,
|
getForms,
|
||||||
createFormFrom,
|
|
||||||
sendTokenEmail,
|
sendTokenEmail,
|
||||||
findUserBy
|
submitAnswer
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { AnswerType } from '@prisma/client'
|
|
||||||
import {
|
import {
|
||||||
Answer,
|
|
||||||
ChoisesQuestion,
|
ChoisesQuestion,
|
||||||
FormSubmission,
|
|
||||||
InputQuestion,
|
InputQuestion,
|
||||||
Variant
|
Variant
|
||||||
} from '../typeDefs/typeDefs.gen'
|
} from '../typeDefs/typeDefs.gen'
|
||||||
@ -14,9 +11,9 @@ type expectedType = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ICheckRightsAndResolve<T> {
|
interface ICheckRightsAndResolve<T> {
|
||||||
user: JwtPayloadType | null
|
|
||||||
expected: expectedType
|
|
||||||
controller: T
|
controller: T
|
||||||
|
expected: expectedType
|
||||||
|
user: JwtPayloadType | null
|
||||||
}
|
}
|
||||||
|
|
||||||
type CheckRightsAndResolve = <ReturnType, ControllerType extends Function>(
|
type CheckRightsAndResolve = <ReturnType, ControllerType extends Function>(
|
||||||
@ -24,15 +21,15 @@ type CheckRightsAndResolve = <ReturnType, ControllerType extends Function>(
|
|||||||
) => Promise<ReturnType>
|
) => Promise<ReturnType>
|
||||||
|
|
||||||
type newForm = {
|
type newForm = {
|
||||||
title: string
|
|
||||||
choisesQuestions: {
|
choisesQuestions: {
|
||||||
create: createChoises[]
|
create: createChoises[]
|
||||||
}
|
}
|
||||||
inputQuestions: { create: InputQuestion[] }
|
inputQuestions: { create: InputQuestion[] }
|
||||||
|
title: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type createChoises = Omit<ChoisesQuestion, 'variants'> & {
|
type createChoises = Omit<ChoisesQuestion, 'variants'> & {
|
||||||
variants: { create: Variant[] }
|
variants: { create: Variant[] }
|
||||||
}
|
}
|
||||||
|
|
||||||
export { CheckRightsAndResolve, newForm, createChoises }
|
export { CheckRightsAndResolve, createChoises, newForm }
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { PrismaClient } from '@prisma/client'
|
|
||||||
import { UserInputError } from 'apollo-server-express'
|
|
||||||
|
|
||||||
import { createDBUser, findDBUserBy } from '../db'
|
import { createDBUser, findDBUserBy } from '../db'
|
||||||
import { IFindUserParams } from '../db/types'
|
import { IFindUserParams } from '../db/types'
|
||||||
import { MutationRegisterArgs, User } from '../typeDefs/typeDefs.gen'
|
import { MutationRegisterArgs, User } from '../typeDefs/typeDefs.gen'
|
||||||
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
import { UserInputError } from 'apollo-server-express'
|
||||||
|
|
||||||
const createUser = async (
|
const createUser = async (
|
||||||
db: PrismaClient,
|
db: PrismaClient,
|
||||||
|
@ -1,20 +1,34 @@
|
|||||||
import { PrismaClient } from '@prisma/client'
|
|
||||||
import { UserInputError } from 'apollo-server-express'
|
|
||||||
import { newForm } from '../controllers/types'
|
|
||||||
import { Answer, MutationRegisterArgs } from '../typeDefs/typeDefs.gen'
|
import { Answer, MutationRegisterArgs } from '../typeDefs/typeDefs.gen'
|
||||||
import { IFindUserParams } from './types'
|
import { IFindUserParams } from './types'
|
||||||
|
import { newForm } from '../controllers/types'
|
||||||
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
import { UserInputError } from 'apollo-server-express'
|
||||||
|
|
||||||
const getDBForm = async (db: PrismaClient, id: number) => {
|
/**
|
||||||
|
* Get form from DataBase
|
||||||
|
*
|
||||||
|
* @async
|
||||||
|
* @param db {PrismaClient} Prisma client object
|
||||||
|
* @param formId {number} Form ID
|
||||||
|
* @param getSubmissions {boolean} Set to true if want to also get form submissions
|
||||||
|
* @example
|
||||||
|
* const form = await getDBForm(db, id, true)
|
||||||
|
*/
|
||||||
|
const getDBForm = async (
|
||||||
|
db: PrismaClient,
|
||||||
|
formId: number,
|
||||||
|
user?: {
|
||||||
|
requesterId: number
|
||||||
|
userId: number
|
||||||
|
}
|
||||||
|
) => {
|
||||||
return await db.form.findOne({
|
return await db.form.findOne({
|
||||||
where: {
|
|
||||||
id
|
|
||||||
},
|
|
||||||
include: {
|
include: {
|
||||||
author: {
|
author: {
|
||||||
select: {
|
select: {
|
||||||
|
email: true,
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true
|
||||||
email: true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
choisesQuestions: {
|
choisesQuestions: {
|
||||||
@ -26,19 +40,32 @@ const getDBForm = async (db: PrismaClient, id: number) => {
|
|||||||
submissions: {
|
submissions: {
|
||||||
include: {
|
include: {
|
||||||
answers: true
|
answers: true
|
||||||
|
},
|
||||||
|
where:
|
||||||
|
user?.requesterId != user?.userId
|
||||||
|
? {
|
||||||
|
user: {
|
||||||
|
id: user?.requesterId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: formId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDBFormByUser = async (db: PrismaClient, id: number) => {
|
/**
|
||||||
|
* Get all forms of user
|
||||||
|
* @param db {PrismaClient} Prisma client object
|
||||||
|
* @param id {number} User ID
|
||||||
|
* @example
|
||||||
|
* const forms = await getDBFormsByUser(db, userId)
|
||||||
|
*/
|
||||||
|
const getDBFormsByUser = async (db: PrismaClient, id: number) => {
|
||||||
return await db.form.findMany({
|
return await db.form.findMany({
|
||||||
where: {
|
|
||||||
author: {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
include: {
|
include: {
|
||||||
choisesQuestions: {
|
choisesQuestions: {
|
||||||
include: {
|
include: {
|
||||||
@ -51,21 +78,26 @@ const getDBFormByUser = async (db: PrismaClient, id: number) => {
|
|||||||
answers: true
|
answers: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
author: {
|
||||||
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDBFormAuthor = async (db: PrismaClient, id: number) => {
|
const getDBFormAuthor = async (db: PrismaClient, id: number) => {
|
||||||
return await db.form.findOne({
|
return await db.form.findOne({
|
||||||
where: {
|
|
||||||
id
|
|
||||||
},
|
|
||||||
select: {
|
select: {
|
||||||
author: {
|
author: {
|
||||||
select: {
|
select: {
|
||||||
id: true
|
id: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -97,10 +129,12 @@ const createDBForm = async (
|
|||||||
) => {
|
) => {
|
||||||
return await db.form.create({
|
return await db.form.create({
|
||||||
data: {
|
data: {
|
||||||
author: { connect: { id } },
|
author: {
|
||||||
title,
|
connect: { id }
|
||||||
|
},
|
||||||
choisesQuestions,
|
choisesQuestions,
|
||||||
inputQuestions
|
inputQuestions,
|
||||||
|
title
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -113,17 +147,19 @@ const submitDBAnswer = async (
|
|||||||
) => {
|
) => {
|
||||||
const res = await db.formSubmission.create({
|
const res = await db.formSubmission.create({
|
||||||
data: {
|
data: {
|
||||||
user: {
|
answers: {
|
||||||
connect: {
|
create: formAnswers
|
||||||
id: userId
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Form: {
|
Form: {
|
||||||
connect: {
|
connect: {
|
||||||
id: formId
|
id: formId
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
answers: { create: formAnswers }
|
user: {
|
||||||
|
connect: {
|
||||||
|
id: userId
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -133,11 +169,11 @@ const submitDBAnswer = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getDBForm,
|
createDBForm,
|
||||||
getDBFormByUser,
|
|
||||||
getDBFormAuthor,
|
|
||||||
createDBUser,
|
createDBUser,
|
||||||
findDBUserBy,
|
findDBUserBy,
|
||||||
createDBForm,
|
getDBForm,
|
||||||
|
getDBFormAuthor,
|
||||||
|
getDBFormsByUser,
|
||||||
submitDBAnswer
|
submitDBAnswer
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { PromiseReturnType } from '@prisma/client'
|
|
||||||
import { getDBForm } from '../db'
|
import { getDBForm } from '../db'
|
||||||
|
import { PromiseReturnType } from '@prisma/client'
|
||||||
|
|
||||||
type FullForm = PromiseReturnType<typeof getDBForm>
|
type FullForm = PromiseReturnType<typeof getDBForm>
|
||||||
|
|
||||||
|
33
src/index.ts
33
src/index.ts
@ -1,40 +1,43 @@
|
|||||||
import { ApolloServer, makeExecutableSchema } from 'apollo-server-express'
|
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import expressJwt from 'express-jwt'
|
import expressJwt from 'express-jwt'
|
||||||
|
import resolvers from './resolvers'
|
||||||
|
import typeDefs from './typeDefs'
|
||||||
|
import { ApolloContextType, JwtPayloadType } from './types'
|
||||||
|
import { ApolloServer, makeExecutableSchema } from 'apollo-server-express'
|
||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
import typeDefs from './typeDefs'
|
|
||||||
import resolvers from './resolvers'
|
|
||||||
import { ApolloContextType, JwtPayloadType } from './types'
|
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
expressJwt({
|
expressJwt({
|
||||||
secret: '' + process.env.JWT_SECRET,
|
algorithms: ['HS256'],
|
||||||
credentialsRequired: false,
|
credentialsRequired: false,
|
||||||
algorithms: ['HS256']
|
secret: '' + process.env.JWT_SECRET
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const server = new ApolloServer({
|
const server = new ApolloServer({
|
||||||
schema: makeExecutableSchema({
|
|
||||||
typeDefs,
|
|
||||||
resolvers
|
|
||||||
}),
|
|
||||||
context: async ({
|
context: async ({
|
||||||
req
|
req
|
||||||
}: {
|
}: {
|
||||||
req: Request & { user: JwtPayloadType }
|
req: Request & {
|
||||||
|
user: JwtPayloadType
|
||||||
|
}
|
||||||
}): Promise<ApolloContextType> => {
|
}): Promise<ApolloContextType> => {
|
||||||
const db = new PrismaClient()
|
const db = new PrismaClient()
|
||||||
const user = req.user || null
|
const user = req.user || null
|
||||||
|
return {
|
||||||
return { db, user }
|
db,
|
||||||
|
user
|
||||||
|
}
|
||||||
},
|
},
|
||||||
debug: false
|
debug: false,
|
||||||
|
schema: makeExecutableSchema({
|
||||||
|
resolvers,
|
||||||
|
typeDefs
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
server.applyMiddleware({ app })
|
server.applyMiddleware({ app })
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import sgMail from "@sendgrid/mail"
|
import sgMail from '@sendgrid/mail'
|
||||||
|
|
||||||
require("dotenv").config()
|
require('dotenv').config()
|
||||||
|
|
||||||
sgMail.setApiKey(process.env.SENDGRID_API_KEY!)
|
sgMail.setApiKey(process.env.SENDGRID_API_KEY!)
|
||||||
|
|
||||||
const sendToken = (username: string, email: string, token: string) => {
|
const sendToken = (username: string, email: string, token: string) => {
|
||||||
return sgMail.send({
|
return sgMail.send({
|
||||||
from: "me@dmitriy.icu",
|
|
||||||
to: email,
|
|
||||||
subject: "Login link",
|
|
||||||
templateId: "d-a9275a4437bf4dd2b9e858f3a57f85d5",
|
|
||||||
dynamicTemplateData: {
|
dynamicTemplateData: {
|
||||||
username: username,
|
|
||||||
siteUrl: process.env.SITE_URL,
|
siteUrl: process.env.SITE_URL,
|
||||||
token: token,
|
token: token,
|
||||||
|
username: username
|
||||||
},
|
},
|
||||||
|
from: 'me@dmitriy.icu',
|
||||||
|
subject: 'Login link',
|
||||||
|
templateId: 'd-a9275a4437bf4dd2b9e858f3a57f85d5',
|
||||||
|
to: email
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
import {
|
import {
|
||||||
checkRightsAndResolve,
|
AnswerResolvers,
|
||||||
getForm,
|
|
||||||
getFormAuthor,
|
|
||||||
getForms,
|
|
||||||
createFormFrom
|
|
||||||
} from '../controllers'
|
|
||||||
import { submitAnswer } from '../controllers/form'
|
|
||||||
import {
|
|
||||||
Form,
|
Form,
|
||||||
|
MutationCreateFormArgs,
|
||||||
|
MutationFormSubmitArgs,
|
||||||
QueryFormArgs,
|
QueryFormArgs,
|
||||||
QuestionResolvers,
|
QuestionResolvers,
|
||||||
Resolver,
|
Resolver,
|
||||||
AnswerResolvers,
|
ServerAnswer
|
||||||
MutationCreateFormArgs,
|
|
||||||
ServerAnswer,
|
|
||||||
MutationFormSubmitArgs
|
|
||||||
} from '../typeDefs/typeDefs.gen'
|
} from '../typeDefs/typeDefs.gen'
|
||||||
import { ApolloContextType } from '../types'
|
import { ApolloContextType } from '../types'
|
||||||
|
import {
|
||||||
|
checkRightsAndResolve,
|
||||||
|
createFormFrom,
|
||||||
|
getForm,
|
||||||
|
getFormAuthor,
|
||||||
|
getForms,
|
||||||
|
submitAnswer
|
||||||
|
} from '../controllers'
|
||||||
|
|
||||||
const formQuery: Resolver<Form, {}, ApolloContextType, QueryFormArgs> = async (
|
const formQuery: Resolver<Form, {}, ApolloContextType, QueryFormArgs> = async (
|
||||||
_,
|
_,
|
||||||
@ -24,17 +24,18 @@ const formQuery: Resolver<Form, {}, ApolloContextType, QueryFormArgs> = async (
|
|||||||
{ db, user }
|
{ db, user }
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const authorId = await getFormAuthor(db, id)
|
const ownerId = await getFormAuthor(db, id)
|
||||||
|
|
||||||
const getFormById = () => getForm(db, id)
|
const getFormById = (userId: number) =>
|
||||||
|
getForm(db, id, { requesterId: userId, userId: ownerId })
|
||||||
|
|
||||||
return await checkRightsAndResolve({
|
return await checkRightsAndResolve({
|
||||||
user,
|
controller: getFormById,
|
||||||
expected: {
|
expected: {
|
||||||
id: 0,
|
id: 0,
|
||||||
self: false
|
self: true
|
||||||
},
|
},
|
||||||
controller: getFormById
|
user
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err
|
return err
|
||||||
@ -53,12 +54,12 @@ const formsQuery: Resolver<Form[], {}, ApolloContextType> = async (
|
|||||||
Form[],
|
Form[],
|
||||||
(userId: number) => Promise<Form[] | null>
|
(userId: number) => Promise<Form[] | null>
|
||||||
>({
|
>({
|
||||||
user,
|
controller: getFormsByUserId,
|
||||||
expected: {
|
expected: {
|
||||||
id: 0,
|
id: 0,
|
||||||
self: true
|
self: true
|
||||||
},
|
},
|
||||||
controller: getFormsByUserId
|
user
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err
|
return err
|
||||||
@ -74,9 +75,12 @@ const createForm: Resolver<
|
|||||||
const createNewForm = (id: number) => createFormFrom(db, params, id)
|
const createNewForm = (id: number) => createFormFrom(db, params, id)
|
||||||
|
|
||||||
return await checkRightsAndResolve({
|
return await checkRightsAndResolve({
|
||||||
user,
|
controller: createNewForm,
|
||||||
expected: { id: 0, self: true },
|
expected: {
|
||||||
controller: createNewForm
|
id: 0,
|
||||||
|
self: true
|
||||||
|
},
|
||||||
|
user
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,9 +93,12 @@ const formSubmit: Resolver<
|
|||||||
const submitNewAnswer = (userId: number) => submitAnswer(db, params, userId)
|
const submitNewAnswer = (userId: number) => submitAnswer(db, params, userId)
|
||||||
|
|
||||||
return await checkRightsAndResolve({
|
return await checkRightsAndResolve({
|
||||||
user,
|
controller: submitNewAnswer,
|
||||||
expected: { id: 0, self: true },
|
expected: {
|
||||||
controller: submitNewAnswer
|
id: 0,
|
||||||
|
self: true
|
||||||
|
},
|
||||||
|
user
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,10 +121,10 @@ const AnswerResolver: AnswerResolvers = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
formQuery,
|
|
||||||
formsQuery,
|
|
||||||
QuestionResolver,
|
|
||||||
AnswerResolver,
|
AnswerResolver,
|
||||||
createForm,
|
createForm,
|
||||||
formSubmit
|
formQuery,
|
||||||
|
formsQuery,
|
||||||
|
formSubmit,
|
||||||
|
QuestionResolver
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,12 @@ const userResolver: Resolver<
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
return await checkRightsAndResolve({
|
return await checkRightsAndResolve({
|
||||||
user,
|
controller: findUserById,
|
||||||
expected: { id: id || 0, self: true },
|
expected: {
|
||||||
controller: findUserById
|
id: id || 0,
|
||||||
|
self: true
|
||||||
|
},
|
||||||
|
user
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return err
|
return err
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { gql } from 'apollo-server-express'
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import { gql } from 'apollo-server-express'
|
||||||
|
|
||||||
const typeDefs = gql(
|
const typeDefs = gql(
|
||||||
fs.readFileSync(__dirname.concat('/typeDefs.gql'), { encoding: 'utf-8' })
|
fs.readFileSync(__dirname.concat('/typeDefs.gql'), { encoding: 'utf-8' })
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
type Query {
|
type Query {
|
||||||
forms: [Form!]!
|
|
||||||
form(id: Int!): Form
|
form(id: Int!): Form
|
||||||
|
forms: [Form!]!
|
||||||
user(id: Int): User
|
user(id: Int): User
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
login(email: String!): serverAnswer
|
|
||||||
register(name: String!, email: String!): serverAnswer
|
|
||||||
createForm(title: String!, questions: String!): Form!
|
createForm(title: String!, questions: String!): Form!
|
||||||
formSubmit(formId: Int!, answers: String!): serverAnswer
|
formSubmit(formId: Int!, answers: String!): serverAnswer
|
||||||
|
login(email: String!): serverAnswer
|
||||||
|
register(name: String!, email: String!): serverAnswer
|
||||||
}
|
}
|
||||||
|
|
||||||
type Form {
|
type Form {
|
||||||
id: Int!
|
|
||||||
title: String!
|
|
||||||
questions: [Question!]!
|
|
||||||
submissions: [FormSubmission!]!
|
|
||||||
dateCreated: String!
|
|
||||||
author: User
|
author: User
|
||||||
|
dateCreated: String!
|
||||||
|
id: Int!
|
||||||
|
questions: [Question!]!
|
||||||
|
submissions: [FormSubmission!]
|
||||||
|
title: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Question {
|
interface Question {
|
||||||
title: String!
|
|
||||||
number: Int!
|
number: Int!
|
||||||
|
title: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChoisesQuestion implements Question {
|
type ChoisesQuestion implements Question {
|
||||||
title: String!
|
|
||||||
variants: [Variant!]!
|
|
||||||
type: ChoiseType!
|
|
||||||
number: Int!
|
number: Int!
|
||||||
|
title: String!
|
||||||
|
type: ChoiseType!
|
||||||
|
variants: [Variant!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Variant {
|
type Variant {
|
||||||
@ -37,14 +37,14 @@ type Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InputQuestion implements Question {
|
type InputQuestion implements Question {
|
||||||
title: String!
|
|
||||||
number: Int!
|
number: Int!
|
||||||
|
title: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type FormSubmission {
|
type FormSubmission {
|
||||||
id: Int!
|
|
||||||
answers: [Answer!]!
|
answers: [Answer!]!
|
||||||
date: String!
|
date: String!
|
||||||
|
id: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Answer {
|
interface Answer {
|
||||||
@ -62,21 +62,21 @@ type ChoiseAnswer implements Answer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ChoiseType {
|
enum ChoiseType {
|
||||||
SELECT
|
|
||||||
CHECK
|
CHECK
|
||||||
CHOOSE
|
CHOOSE
|
||||||
|
SELECT
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AnswerType {
|
enum AnswerType {
|
||||||
INPUT
|
|
||||||
CHOISE
|
CHOISE
|
||||||
|
INPUT
|
||||||
}
|
}
|
||||||
|
|
||||||
type User {
|
type User {
|
||||||
name: String!
|
|
||||||
email: String!
|
email: String!
|
||||||
id: Int!
|
|
||||||
forms: [Form!]
|
forms: [Form!]
|
||||||
|
id: Int!
|
||||||
|
name: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type serverAnswer {
|
type serverAnswer {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user