From 4b99d2c3e4d45673babaa77d95868d8ea10f0e3e Mon Sep 17 00:00:00 2001 From: Lucas Cordeiro Date: Tue, 28 Dec 2021 16:19:12 -0300 Subject: [PATCH] Add guard against logged out users (#243) --- src/modules/study/studySession.ts | 2 +- src/resolvers/deck/createDeck.ts | 6 +++++- src/resolvers/deck/deleteDeck.ts | 6 +++++- src/resolvers/deck/listDecks.ts | 6 +++++- src/resolvers/deck/publish.ts | 6 +++++- src/resolvers/deck/updateDeck.ts | 6 +++++- src/resolvers/field/updateField.ts | 14 +++++++++++--- src/resolvers/model/addFieldToModel.ts | 6 +++++- src/resolvers/model/addTemplateToModel.ts | 6 +++++- src/resolvers/model/createModel.ts | 6 +++++- src/resolvers/model/deleteModel.ts | 6 +++++- src/resolvers/model/removeFieldFromModel.ts | 12 ++++++++++-- src/resolvers/model/updateModel.ts | 6 +++++- src/resolvers/note/createNote.ts | 10 +++++++--- src/resolvers/note/deleteNote.ts | 6 +++++- src/resolvers/note/noteById.ts | 6 +++++- src/resolvers/statistics/deckStatistics.ts | 6 +++++- src/resolvers/user/createUser.ts | 10 +++++++--- 18 files changed, 101 insertions(+), 25 deletions(-) diff --git a/src/modules/study/studySession.ts b/src/modules/study/studySession.ts index 982226c..d433b97 100644 --- a/src/modules/study/studySession.ts +++ b/src/modules/study/studySession.ts @@ -13,7 +13,7 @@ const sumByStatus = (logs: RevisionLogDocument[], status: FlashcardStatus) => { } export const studyFlashcardsByDeck = async (deckId: string, ctx: Context) => { - const userTimeZone = ctx.user?.preferences?.zoneInfo ?? 'UTC' + const userTimeZone = ctx.user!.preferences?.zoneInfo ?? 'UTC' const deck = await ctx.deckLoader.load(deckId) diff --git a/src/resolvers/deck/createDeck.ts b/src/resolvers/deck/createDeck.ts index e3f9714..6966b3c 100644 --- a/src/resolvers/deck/createDeck.ts +++ b/src/resolvers/deck/createDeck.ts @@ -27,10 +27,14 @@ export const createDeck = mutationWithClientMutationId({ deck: { type: DeckType, description: 'Created deck' }, }, mutateAndGetPayload: async ({ title, description }, { user }: Context) => { + if (!user) { + return { deck: null } + } + const deck = await DeckModel.create({ title, description, - ownerId: user?._id, + ownerId: user._id, slug: '', published: false, configuration: defaultDeckConfig, diff --git a/src/resolvers/deck/deleteDeck.ts b/src/resolvers/deck/deleteDeck.ts index 16e02f5..e201548 100644 --- a/src/resolvers/deck/deleteDeck.ts +++ b/src/resolvers/deck/deleteDeck.ts @@ -14,9 +14,13 @@ export const deleteDeck = mutationWithClientMutationId({ deck: { type: DeckType, description: 'Deleted deck' }, }, mutateAndGetPayload: async ({ id }, { user }: Context) => { + if (!user) { + return { deck: null } + } + const { id: deckId } = fromGlobalId(id) - const deck = await DeckModel.findOne({ _id: deckId, ownerId: user?._id }) + const deck = await DeckModel.findOne({ _id: deckId, ownerId: user._id }) if (!deck) { throw new Error('Deck not found') diff --git a/src/resolvers/deck/listDecks.ts b/src/resolvers/deck/listDecks.ts index 75fe0a3..423b408 100644 --- a/src/resolvers/deck/listDecks.ts +++ b/src/resolvers/deck/listDecks.ts @@ -32,7 +32,11 @@ export const decks: GraphQLFieldConfig = { }, }, resolve: async (_, { studyOnly }, ctx) => { - let decks = await DeckModel.find({ ownerId: ctx.user?._id }) + if (!ctx.user) { + return [] + } + + let decks = await DeckModel.find({ ownerId: ctx.user._id }) if (studyOnly) { // eslint-disable-next-line require-atomic-updates diff --git a/src/resolvers/deck/publish.ts b/src/resolvers/deck/publish.ts index e1ed8c4..db47d2d 100644 --- a/src/resolvers/deck/publish.ts +++ b/src/resolvers/deck/publish.ts @@ -54,11 +54,15 @@ export const unpublishDeck = mutationWithClientMutationId({ }, outputFields: { deck: { type: DeckType } }, mutateAndGetPayload: ({ id }, { user }: Context) => { + if (!user) { + return { deck: null } + } + const { id: deckId } = fromGlobalId(id) return { deck: DeckModel.findOneAndUpdate( - { _id: deckId, ownerId: user?._id }, + { _id: deckId, ownerId: user._id }, { published: false }, { new: true, diff --git a/src/resolvers/deck/updateDeck.ts b/src/resolvers/deck/updateDeck.ts index 5acfad5..916bc29 100644 --- a/src/resolvers/deck/updateDeck.ts +++ b/src/resolvers/deck/updateDeck.ts @@ -16,11 +16,15 @@ export const updateDeck = mutationWithClientMutationId({ deck: { type: DeckType, description: 'Updated deck' }, }, mutateAndGetPayload: ({ id, title, description }, { user }: Context) => { + if (!user) { + return { deck: null } + } + const { id: deckId } = fromGlobalId(id) return { deck: DeckModel.findOneAndUpdate( - { _id: deckId, ownerId: user?._id }, + { _id: deckId, ownerId: user._id }, { title, description }, { new: true } ), diff --git a/src/resolvers/field/updateField.ts b/src/resolvers/field/updateField.ts index 770874a..6f52a90 100644 --- a/src/resolvers/field/updateField.ts +++ b/src/resolvers/field/updateField.ts @@ -23,16 +23,24 @@ export const updateField = mutationWithClientMutationId({ { id, name }: UpdateFieldInput, { user }: Context ) => { + if (!user) { + return { field: null } + } + const { id: fieldId } = fromGlobalId(id) const field = await FieldModel.findById(fieldId) + if (!field) { + return { field: null } + } + const fieldModel = await ModelModel.findOne({ - _id: field?.modelId, - ownerId: user?._id, + _id: field.modelId, + ownerId: user._id, }) - if (!fieldModel || !field) { + if (!fieldModel) { throw new GraphQLError('User is not authorized') } diff --git a/src/resolvers/model/addFieldToModel.ts b/src/resolvers/model/addFieldToModel.ts index 334511d..6279d02 100644 --- a/src/resolvers/model/addFieldToModel.ts +++ b/src/resolvers/model/addFieldToModel.ts @@ -22,11 +22,15 @@ export const addFieldToModel: GraphQLFieldConfig = field: { type: FieldType }, }, mutateAndGetPayload: async (args: AddFieldInput, { user }: Context) => { + if (!user) { + return { field: null } + } + const { id: modelId } = fromGlobalId(args.modelId) const model = await ModelModel.findOne({ _id: modelId, - ownerId: user?._id, + ownerId: user._id, }) if (!model) { diff --git a/src/resolvers/model/addTemplateToModel.ts b/src/resolvers/model/addTemplateToModel.ts index ceb4c3f..90933c8 100644 --- a/src/resolvers/model/addTemplateToModel.ts +++ b/src/resolvers/model/addTemplateToModel.ts @@ -29,6 +29,10 @@ export const addTemplateToModel: GraphQLFieldConfig< args: AddTemplateInput, { user, modelLoader }: Context ) => { + if (!user) { + return { template: null } + } + const { id: modelId } = fromGlobalId(args.modelId) const model = await modelLoader.load(modelId) @@ -36,7 +40,7 @@ export const addTemplateToModel: GraphQLFieldConfig< const template = await TemplateModel.create({ name: args.name, modelId: model._id, - ownerId: user?._id, + ownerId: user._id, frontSide: null, backSide: null, }) diff --git a/src/resolvers/model/createModel.ts b/src/resolvers/model/createModel.ts index 9f118f3..88fb7a4 100644 --- a/src/resolvers/model/createModel.ts +++ b/src/resolvers/model/createModel.ts @@ -37,9 +37,13 @@ export const createModel: GraphQLFieldConfig = { name, fields, templates }: CreateModelInput, { user }: Context ) => { + if (!user) { + return { model: null } + } + const model = await ModelModel.create({ name, - ownerId: user?._id, + ownerId: user._id, }) await FieldModel.create( diff --git a/src/resolvers/model/deleteModel.ts b/src/resolvers/model/deleteModel.ts index 857410e..a392f12 100644 --- a/src/resolvers/model/deleteModel.ts +++ b/src/resolvers/model/deleteModel.ts @@ -17,11 +17,15 @@ export const deleteModel: GraphQLFieldConfig = model: { type: ModelType }, }, mutateAndGetPayload: async ({ id }, { user }: Context) => { + if (!user) { + return { model: null } + } + const { id: modelId } = fromGlobalId(id) const model = await ModelModel.findOne({ _id: modelId, - ownerId: user?._id, + ownerId: user._id, }) if (!model) { diff --git a/src/resolvers/model/removeFieldFromModel.ts b/src/resolvers/model/removeFieldFromModel.ts index 771f6f8..0ae99a5 100644 --- a/src/resolvers/model/removeFieldFromModel.ts +++ b/src/resolvers/model/removeFieldFromModel.ts @@ -23,13 +23,21 @@ export const removeFieldFromModel: GraphQLFieldConfig< field: { type: FieldType }, }, mutateAndGetPayload: async (args: RemoveFieldInput, { user }: Context) => { + if (!user) { + return { field: null } + } + const { id: fieldId } = fromGlobalId(args.fieldId) const field = await FieldModel.findById(fieldId) + if (!field) { + return { field: null } + } + const fieldModel = await ModelModel.findOne({ - _id: field?.modelId, - ownerId: user?._id, + _id: field.modelId, + ownerId: user._id, }) if (!field || !fieldModel) { diff --git a/src/resolvers/model/updateModel.ts b/src/resolvers/model/updateModel.ts index fb87ab1..b9d90f1 100644 --- a/src/resolvers/model/updateModel.ts +++ b/src/resolvers/model/updateModel.ts @@ -23,11 +23,15 @@ export const updateModel: GraphQLFieldConfig = { id, name }: UpdateModelInput, { user }: Context ) => { + if (!user) { + return { model: null } + } + const { id: modelId } = fromGlobalId(id) return { model: ModelModel.findOneAndUpdate( - { _id: modelId, ownerId: user?._id }, + { _id: modelId, ownerId: user._id }, { name }, { new: true } ), diff --git a/src/resolvers/note/createNote.ts b/src/resolvers/note/createNote.ts index b2c7534..a8ff6a3 100644 --- a/src/resolvers/note/createNote.ts +++ b/src/resolvers/note/createNote.ts @@ -37,13 +37,17 @@ export const createNote = mutationWithClientMutationId({ }, outputFields: { note: { type: NoteType } }, mutateAndGetPayload: async (args: CreateNoteMutationInput, { user }) => { + if (!user) { + return { note: null } + } + const { id: deckId } = fromGlobalId(args.deckId) const { id: modelId } = fromGlobalId(args.modelId) - const deck = await DeckModel.findOne({ _id: deckId, ownerId: user?._id }) + const deck = await DeckModel.findOne({ _id: deckId, ownerId: user._id }) const model = await ModelModel.findOne({ _id: modelId, - ownerId: user?._id, + ownerId: user._id, }) if (!deck || !model) { @@ -63,7 +67,7 @@ export const createNote = mutationWithClientMutationId({ const note = await NoteModel.create({ modelId: model._id, deckId: deck._id, - ownerId: user!._id, + ownerId: user._id, values: modelFields.map((field) => { const modelFieldId = field._id as Types.ObjectId diff --git a/src/resolvers/note/deleteNote.ts b/src/resolvers/note/deleteNote.ts index 3028b07..46db71a 100644 --- a/src/resolvers/note/deleteNote.ts +++ b/src/resolvers/note/deleteNote.ts @@ -12,11 +12,15 @@ export const deleteNote = mutationWithClientMutationId({ }, outputFields: { note: { type: NoteType } }, mutateAndGetPayload: async (args: { noteId: string }, ctx) => { + if (!ctx.user) { + return { note: null } + } + const { id: noteId } = fromGlobalId(args.noteId) const note = await NoteModel.findOne({ _id: noteId, - ownerId: ctx.user?._id, + ownerId: ctx.user._id, }) if (!note) { diff --git a/src/resolvers/note/noteById.ts b/src/resolvers/note/noteById.ts index 3715d44..5d00575 100644 --- a/src/resolvers/note/noteById.ts +++ b/src/resolvers/note/noteById.ts @@ -10,8 +10,12 @@ export const note: GraphQLFieldConfig = { description: "Get single note by it's id", args: { id: { type: GraphQLNonNull(GraphQLID) } }, resolve: async (_, args, { user }) => { + if (!user) { + return null + } + const { id: noteId } = fromGlobalId(args.id) - const userDecks = await DeckModel.find({ ownerId: user?._id }) + const userDecks = await DeckModel.find({ ownerId: user._id }) const note = await NoteModel.findOne({ _id: noteId, diff --git a/src/resolvers/statistics/deckStatistics.ts b/src/resolvers/statistics/deckStatistics.ts index f747dbb..83e33ce 100644 --- a/src/resolvers/statistics/deckStatistics.ts +++ b/src/resolvers/statistics/deckStatistics.ts @@ -20,13 +20,17 @@ export const deckStatistics: GraphQLFieldConfig< deckId: { type: GraphQLID }, }, resolve: async (_, args, ctx) => { + if (!ctx.user) { + return null + } + let deck if (args.deckId) { const { id: deckId } = fromGlobalId(args.deckId) deck = await ctx.deckLoader.load(deckId) } else { - deck = await DeckModel.findOne({ ownerId: ctx.user?._id }) + deck = await DeckModel.findOne({ ownerId: ctx.user._id }) } if (!deck) { diff --git a/src/resolvers/user/createUser.ts b/src/resolvers/user/createUser.ts index e66c0e3..353a62b 100644 --- a/src/resolvers/user/createUser.ts +++ b/src/resolvers/user/createUser.ts @@ -61,8 +61,12 @@ export const createUser = mutationWithClientMutationId({ }, mutateAndGetPayload: async ( { username, email, password, locale, zoneInfo }: CreateUserArgs, - { t }: Context + { t, user: loggedInUser }: Context ) => { + if (loggedInUser) { + return { user: null } + } + const user = new UserModel({ username, email, @@ -71,7 +75,7 @@ export const createUser = mutationWithClientMutationId({ }) try { - await user?.validate() + await user.validate() } catch (validation) { if (validation instanceof Error.ValidationError) { return { @@ -93,7 +97,7 @@ export const createUser = mutationWithClientMutationId({ } try { - await user?.hashifyAndSave() + await user.hashifyAndSave() } catch (err) { if (err instanceof MongoError) { // duplicate key error