Skip to content

Commit

Permalink
Merge pull request #239 from UofA-Blueprint/fix/dish-user-return
Browse files Browse the repository at this point in the history
fix: only admin & volunteer can return dish
  • Loading branch information
royayush1 authored Aug 26, 2023
2 parents b85594b + 6e94230 commit 5653b2a
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
23 changes: 17 additions & 6 deletions backend/src/controllers/dish.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request, Response } from 'express'
import { Condition, Dish } from '../models/dish'
import { Condition } from '../models/dish'
import { Transaction } from '../models/transaction'
import {
getDish,
Expand All @@ -16,12 +16,15 @@ import {
} from '../services/dish'
import { CustomRequest } from '../middlewares/auth'
import Logger from '../utils/logger'
import { verifyIfUserAdmin } from '../services/users'
import { registerTransaction, getLatestTransaction, getLatestTransactionBydishId } from '../services/transactions'
import { verifyIfUserAdmin, verifyIfUserVolunteer } from '../services/users'
import {
registerTransaction,
getLatestTransactionByTstamp,
getLatestTransactionByTstampAndDishId,
} from '../services/transactions'
import { getQrCode } from '../services/qrCode'
import { db } from '../services/firebase'
import nodeConfig from 'config'
import { time } from 'console'

export const getDishes = async (req: Request, res: Response) => {
let userClaims = (req as CustomRequest).firebase
Expand Down Expand Up @@ -251,6 +254,14 @@ export const returnDish = async (req: Request, res: Response) => {
let { condition } = req.body.returned

let userClaims = (req as CustomRequest).firebase
if (!verifyIfUserAdmin(userClaims) && !verifyIfUserVolunteer(userClaims)) {
Logger.error({
module: 'dish.controller',
message: 'User is not admin',
statusCode: 403,
})
return res.status(403).json({ error: 'forbidden' })
}
try {
let qrCodeExits
let associatedDish
Expand Down Expand Up @@ -286,7 +297,7 @@ export const returnDish = async (req: Request, res: Response) => {
}

// update the existing transaction with the returned property
ongoingTransaction = await getLatestTransaction(userClaims, parseInt(qid, 10))
ongoingTransaction = await getLatestTransactionByTstamp(parseInt(qid, 10))
if (!ongoingTransaction) {
Logger.error({
module: 'dish.controller',
Expand Down Expand Up @@ -335,7 +346,7 @@ export const returnDish = async (req: Request, res: Response) => {
})
return res.status(400).json({ error: 'operation_not_allowed', message: 'Dish not borrowed' })
}
ongoingTransaction = await getLatestTransactionBydishId(userClaims, id!)
ongoingTransaction = await getLatestTransactionByTstampAndDishId(id!)
if (!ongoingTransaction) {
Logger.error({
module: 'dish.controller',
Expand Down
44 changes: 44 additions & 0 deletions backend/src/services/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,50 @@ export const getLatestTransaction = async (userClaims: DecodedIdToken, qid: numb
}
}

/**
* Fetches the latest transaction by timestamp and qid
* @param qid number
* @returns Promise<Transaction>
*/
export const getLatestTransactionByTstamp = async (qid: number) => {
let transactionQuery = await db
.collection(nodeConfig.get('collections.transactions'))
.where('dish.qid', '==', qid)
.where('returned.timestamp', '==', '')
.orderBy('timestamp', 'desc')
.limit(1)
.get()
if (transactionQuery.empty) {
return null
}
return {
...transactionQuery.docs[0].data(),
id: transactionQuery.docs[0].id,
}
}

/**
* Fetches the latest transaction by timestamp and dishId
* @param dishId string
* @returns Promise<Transaction>
*/
export const getLatestTransactionByTstampAndDishId = async (dishId: string) => {
let transactionQuery = await db
.collection(nodeConfig.get('collections.transactions'))
.where('dish.id', '==', dishId)
.where('returned.timestamp', '==', '')
.orderBy('timestamp', 'desc')
.limit(1)
.get()
if (transactionQuery.empty) {
return null
}
return {
...transactionQuery.docs[0].data(),
id: transactionQuery.docs[0].id,
}
}

export const getLatestTransactionBydishId = async (userClaims: DecodedIdToken, dishId: string) => {
let snapshot = await db
.collection(nodeConfig.get('collections.transactions'))
Expand Down
4 changes: 4 additions & 0 deletions backend/src/services/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export const verifyIfUserAdmin = (userClaims: DecodedIdToken) => {
return userClaims.role === 'admin'
}

export const verifyIfUserVolunteer = (userClaims: DecodedIdToken) => {
return userClaims.role === 'volunteer'
}

export const verifyRole = (role: string) => {
return role === 'admin' || role === 'volunteer' || role === 'customer'
}
Expand Down
4 changes: 2 additions & 2 deletions backend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
"noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
"noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
Expand Down

0 comments on commit 5653b2a

Please sign in to comment.