From aa8fdda13d00fe5ee7fe26d54fb48189ea30a6d6 Mon Sep 17 00:00:00 2001 From: Dm1tr1y147 Date: Thu, 8 Oct 2020 03:22:58 +0500 Subject: [PATCH] Added 'form' authorization --- src/controllers/index.ts | 28 ++++++++++++++++++++++++++-- src/db/index.ts | 17 ++++++++++++++++- src/index.ts | 12 ++++++++---- src/resolvers/Form.ts | 14 +++++++++++--- src/resolvers/User.ts | 4 ++-- src/types.ts | 5 +++-- 6 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 161a37b..4e49217 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,8 +1,9 @@ import { PrismaClient } from "@prisma/client" -import { getDBForm, getDBFormByUser } from "../db" +import { getDBForm, getDBFormAuthor, getDBFormByUser } from "../db" import { FullForm } from "../db/types" import { Form as GraphqlForm, FormSubmission } from "../typeDefs/typeDefs.gen" +import { JwtPayloadType } from "../types" const getForm = async ( db: PrismaClient, @@ -50,4 +51,27 @@ const getForms = async ( return forms } -export { getForm, getForms } +const checkRightsAndResolve = async ( + user: JwtPayloadType, + expected: JwtPayloadType, + controller: any +) => { + if ( + (!expected.id || user.id == expected.id) && + (!expected.admin || expected.admin) + ) + return controller() + throw new Error("Authentification error") +} + +const getFormAuthor = async (db: PrismaClient, id: number) => { + const author = await getDBFormAuthor(db, id) + + if (!author) throw Error("Not found") + + const authorId = author.author.id + + return authorId +} + +export { getForm, getForms, checkRightsAndResolve, getFormAuthor } diff --git a/src/db/index.ts b/src/db/index.ts index 2bb75ff..2f6976b 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -45,4 +45,19 @@ const getDBFormByUser = async (db: PrismaClient, id: number) => { }) } -export { getDBForm, getDBFormByUser } +const getDBFormAuthor = async (db: PrismaClient, id: number) => { + return await db.form.findOne({ + where: { + id, + }, + select: { + author: { + select: { + id: true, + }, + }, + }, + }) +} + +export { getDBForm, getDBFormByUser, getDBFormAuthor } diff --git a/src/index.ts b/src/index.ts index 3e19246..730041e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,11 @@ import { ApolloServer } from "apollo-server-express" import express from "express" import expressJwt from "express-jwt" -import jwt from 'jsonwebtoken' import { PrismaClient } from "@prisma/client" import typeDefs from "./typeDefs" import resolvers from "./resolvers" -import { ApolloContextType } from "./types" +import { ApolloContextType, JwtPayloadType } from "./types" const app = express() @@ -21,10 +20,15 @@ app.use( const server = new ApolloServer({ typeDefs, resolvers, - context: async ({ req }): Promise => { + context: async ({ + req, + }: { + req: Request & { user: JwtPayloadType } + }): Promise => { const db = new PrismaClient() + const user = req.user || null - return { db } + return { db, user } }, }) diff --git a/src/resolvers/Form.ts b/src/resolvers/Form.ts index 80effcb..8d1cdab 100644 --- a/src/resolvers/Form.ts +++ b/src/resolvers/Form.ts @@ -1,4 +1,4 @@ -import { getForm, getForms } from "../controllers" +import { checkRightsAndResolve, getForm, getFormAuthor, getForms } from "../controllers" import { Form, QueryFormArgs, @@ -11,10 +11,18 @@ import { ApolloContextType } from "../types" const formQuery: Resolver = async ( _, { id }, - { db } + { db, user } ) => { try { - return await getForm(db, id) + const authorId = await getFormAuthor(db, id) + + const getFormById = () => getForm(db, id) + + return await checkRightsAndResolve( + user!, + { id: authorId, admin: false }, + getFormById + ) } catch (err) { return err } diff --git a/src/resolvers/User.ts b/src/resolvers/User.ts index d90b0b0..eef7a5b 100644 --- a/src/resolvers/User.ts +++ b/src/resolvers/User.ts @@ -1,6 +1,6 @@ import jwt from "jsonwebtoken" import { MutationLoginArgs, Resolver, User } from "../typeDefs/typeDefs.gen" -import { ApolloContextType, JwtPayload } from "../types" +import { ApolloContextType, JwtPayloadType } from "../types" const loginResolver: Resolver< User, @@ -9,7 +9,7 @@ const loginResolver: Resolver< MutationLoginArgs > = async (_, { id, admin }, { db }) => { try { - const payload: JwtPayload = { + const payload: JwtPayloadType = { id, admin, } diff --git a/src/types.ts b/src/types.ts index 9b4e7ba..099475e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,10 +2,11 @@ import { PrismaClient } from "@prisma/client" import {} from 'express-jwt' export type ApolloContextType = { - db: PrismaClient + db: PrismaClient, + user: JwtPayloadType | null } -export type JwtPayload = { +export type JwtPayloadType = { id: number, admin: boolean } \ No newline at end of file