From a95a26362398b6d5bea33a848b1402b32abf7dca Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sat, 29 Mar 2025 00:55:17 -0400 Subject: [PATCH 01/33] Updated auth --- apps/backend/src/auth/jwt.guard.ts | 5 +++++ apps/backend/src/auth/jwt.strategy.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 apps/backend/src/auth/jwt.guard.ts diff --git a/apps/backend/src/auth/jwt.guard.ts b/apps/backend/src/auth/jwt.guard.ts new file mode 100644 index 000000000..f65f8455d --- /dev/null +++ b/apps/backend/src/auth/jwt.guard.ts @@ -0,0 +1,5 @@ +import { Injectable } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; + +@Injectable() +export class JwtGuard extends AuthGuard('jwt') {} diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index 906773f41..b58a0a4da 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { passportJwtSecret } from 'jwks-rsa'; import { ExtractJwt, Strategy } from 'passport-jwt'; From d9e698e5be72cd9f3036788d4461f750eabaa2c4 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sat, 29 Mar 2025 15:14:15 -0400 Subject: [PATCH 02/33] Tried fixing JWT Strategy --- apps/backend/src/auth/roles.guard.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/backend/src/auth/roles.guard.ts b/apps/backend/src/auth/roles.guard.ts index 2dd548686..d2dee170a 100644 --- a/apps/backend/src/auth/roles.guard.ts +++ b/apps/backend/src/auth/roles.guard.ts @@ -1,4 +1,9 @@ -import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; +import { + Injectable, + CanActivate, + ExecutionContext, + UseInterceptors, +} from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { Role } from '../users/types'; import { ROLES_KEY } from './roles.decorator'; From ea324ba59db6bb7cc91d3d314b8f8ff5c8a74770 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 30 Mar 2025 14:36:27 -0400 Subject: [PATCH 03/33] Updated auth --- apps/backend/src/auth/jwt.strategy.ts | 1 + apps/backend/src/auth/roles.guard.ts | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index b58a0a4da..28af416e5 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -10,6 +10,7 @@ import { User } from '../users/user.entity'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor(private usersService: UsersService) { + console.log('IN THE JWT STRATEGY'); const cognitoAuthority = `https://cognito-idp.${CognitoAuthConfig.region}.amazonaws.com/${CognitoAuthConfig.userPoolId}`; super({ diff --git a/apps/backend/src/auth/roles.guard.ts b/apps/backend/src/auth/roles.guard.ts index d2dee170a..2dd548686 100644 --- a/apps/backend/src/auth/roles.guard.ts +++ b/apps/backend/src/auth/roles.guard.ts @@ -1,9 +1,4 @@ -import { - Injectable, - CanActivate, - ExecutionContext, - UseInterceptors, -} from '@nestjs/common'; +import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { Role } from '../users/types'; import { ROLES_KEY } from './roles.decorator'; From f68d4a3eeca849dfd7e1aa1e39c47d296a1d838c Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Mon, 31 Mar 2025 01:23:50 -0400 Subject: [PATCH 04/33] Finished general authentication for both frontend and backend pages --- apps/backend/src/auth/jwt.strategy.ts | 6 ++++-- apps/backend/src/pantries/pantries.controller.ts | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index 28af416e5..168fd8288 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -9,8 +9,10 @@ import { User } from '../users/user.entity'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { - constructor(private usersService: UsersService) { - console.log('IN THE JWT STRATEGY'); + constructor( + private usersService: UsersService, + private authService: AuthService, + ) { const cognitoAuthority = `https://cognito-idp.${CognitoAuthConfig.region}.amazonaws.com/${CognitoAuthConfig.userPoolId}`; super({ diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index 7ed7764fd..c3332ec2c 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -27,6 +27,8 @@ import { OrdersService } from '../orders/order.service'; import { Public } from '../auth/public.decorator'; @Controller('pantries') +// @UseInterceptors(CurrentUserInterceptor) +@UseGuards(AuthGuard('jwt')) export class PantriesController { constructor( private pantriesService: PantriesService, From d8a1414524e54a377e5ca73b3e394096d2d5aba8 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Tue, 1 Apr 2025 17:35:11 -0400 Subject: [PATCH 05/33] Final commit for this branch --- apps/backend/src/donationItems/donationItems.controller.ts | 1 + apps/backend/src/donations/donations.controller.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/backend/src/donationItems/donationItems.controller.ts b/apps/backend/src/donationItems/donationItems.controller.ts index 6435dd9ca..bebe5c400 100644 --- a/apps/backend/src/donationItems/donationItems.controller.ts +++ b/apps/backend/src/donationItems/donationItems.controller.ts @@ -16,6 +16,7 @@ import { CreateMultipleDonationItemsDto } from './dtos/create-donation-items.dto @Controller('donation-items') //@UseInterceptors() +@UseGuards(AuthGuard('jwt')) export class DonationItemsController { constructor(private donationItemsService: DonationItemsService) {} diff --git a/apps/backend/src/donations/donations.controller.ts b/apps/backend/src/donations/donations.controller.ts index 6bcd2a7e8..8940a3dae 100644 --- a/apps/backend/src/donations/donations.controller.ts +++ b/apps/backend/src/donations/donations.controller.ts @@ -15,6 +15,7 @@ import { DonationService } from './donations.service'; import { DonationStatus } from './types'; @Controller('donations') +@UseGuards(AuthGuard('jwt')) export class DonationsController { constructor(private donationService: DonationService) {} From bafe7b10b99c89f63955e3fb2009bd52743e53d9 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 10 Aug 2025 16:27:33 -0400 Subject: [PATCH 06/33] Revisions made with Sam!!! --- .../src/pantries/pantries.controller.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index c3332ec2c..872f085c5 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -28,7 +28,7 @@ import { Public } from '../auth/public.decorator'; @Controller('pantries') // @UseInterceptors(CurrentUserInterceptor) -@UseGuards(AuthGuard('jwt')) +@UseGuards(AuthGuard('jwt'), RolesGuard) export class PantriesController { constructor( private pantriesService: PantriesService, @@ -42,6 +42,16 @@ export class PantriesController { } @Roles(Role.PANTRY, Role.ADMIN) + @UseGuards(RolesGuard) + @Get('/:pantryId/ssf-contact') + async getSSFRep( + @Param('pantryId', ParseIntPipe) pantryId: number, + ): Promise { + return this.pantriesService.findSSFRep(pantryId); + } + + @Roles(Role.PANTRY, Role.ADMIN) + @UseGuards(RolesGuard) @Get('/:pantryId') async getPantry( @Param('pantryId', ParseIntPipe) pantryId: number, @@ -302,7 +312,8 @@ export class PantriesController { } @Roles(Role.ADMIN) - @Patch('/:pantryId/approve') + @UseGuards(RolesGuard) + @Post('/approve/:pantryId') async approvePantry( @Param('pantryId', ParseIntPipe) pantryId: number, ): Promise { @@ -310,7 +321,8 @@ export class PantriesController { } @Roles(Role.ADMIN) - @Patch('/:pantryId/deny') + @UseGuards(RolesGuard) + @Post('/deny/:pantryId') async denyPantry( @Param('pantryId', ParseIntPipe) pantryId: number, ): Promise { From 1a120826234761c246c8f413e1fd71d7cde9b6bf Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Mon, 19 Jan 2026 13:10:52 -0500 Subject: [PATCH 07/33] Full implementation of backend role-based auth --- apps/backend/src/auth/jwt.strategy.ts | 2 +- apps/backend/src/donations/donations.controller.ts | 1 - apps/backend/src/pantries/pantries.controller.ts | 5 ++--- apps/frontend/src/api/apiClient.ts | 1 + apps/frontend/src/aws-exports.ts | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index 168fd8288..236ec0ac3 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -36,4 +36,4 @@ export class JwtStrategy extends PassportStrategy(Strategy) { const dbUser = await this.usersService.findUserByCognitoId(payload.sub); return dbUser; } -} +} \ No newline at end of file diff --git a/apps/backend/src/donations/donations.controller.ts b/apps/backend/src/donations/donations.controller.ts index 8940a3dae..6bcd2a7e8 100644 --- a/apps/backend/src/donations/donations.controller.ts +++ b/apps/backend/src/donations/donations.controller.ts @@ -15,7 +15,6 @@ import { DonationService } from './donations.service'; import { DonationStatus } from './types'; @Controller('donations') -@UseGuards(AuthGuard('jwt')) export class DonationsController { constructor(private donationService: DonationService) {} diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index 872f085c5..db30a244e 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -26,16 +26,15 @@ import { Order } from '../orders/order.entity'; import { OrdersService } from '../orders/order.service'; import { Public } from '../auth/public.decorator'; -@Controller('pantries') -// @UseInterceptors(CurrentUserInterceptor) @UseGuards(AuthGuard('jwt'), RolesGuard) +@Controller('pantries') export class PantriesController { constructor( private pantriesService: PantriesService, private ordersService: OrdersService, ) {} - @Roles(Role.ADMIN) + @Roles(Role.VOLUNTEER) @Get('/pending') async getPendingPantries(): Promise { return this.pantriesService.getPendingPantries(); diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index 09a317451..b8b9369f1 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -36,6 +36,7 @@ export class ApiClient { this.axiosInstance.interceptors.request.use( (config: InternalAxiosRequestConfig) => { const token = this.accessToken || localStorage.getItem('accessToken'); + console.log('Attaching token to request:', token); if (token) { config.headers = config.headers || {}; config.headers['Authorization'] = `Bearer ${token}`; diff --git a/apps/frontend/src/aws-exports.ts b/apps/frontend/src/aws-exports.ts index ad17bcd30..02899587f 100644 --- a/apps/frontend/src/aws-exports.ts +++ b/apps/frontend/src/aws-exports.ts @@ -10,4 +10,4 @@ const CognitoAuthConfig = { }, }, }; -export default CognitoAuthConfig; +export default CognitoAuthConfig; \ No newline at end of file From d9e48b4f44ae7fba74d16ad192da6fc7f23b732e Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Mon, 19 Jan 2026 13:13:34 -0500 Subject: [PATCH 08/33] prettier --- apps/backend/src/auth/jwt.strategy.ts | 2 +- apps/frontend/src/aws-exports.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index 236ec0ac3..168fd8288 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -36,4 +36,4 @@ export class JwtStrategy extends PassportStrategy(Strategy) { const dbUser = await this.usersService.findUserByCognitoId(payload.sub); return dbUser; } -} \ No newline at end of file +} diff --git a/apps/frontend/src/aws-exports.ts b/apps/frontend/src/aws-exports.ts index 02899587f..ad17bcd30 100644 --- a/apps/frontend/src/aws-exports.ts +++ b/apps/frontend/src/aws-exports.ts @@ -10,4 +10,4 @@ const CognitoAuthConfig = { }, }, }; -export default CognitoAuthConfig; \ No newline at end of file +export default CognitoAuthConfig; From d0d28febd940493fc360e8bad4389cac84c73d08 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Fri, 23 Jan 2026 12:51:25 -0500 Subject: [PATCH 09/33] Fixed user flow to use a cognito id hardcoded into the database --- apps/backend/src/auth/jwt.strategy.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index 168fd8288..295a132ad 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -11,7 +11,6 @@ import { User } from '../users/user.entity'; export class JwtStrategy extends PassportStrategy(Strategy) { constructor( private usersService: UsersService, - private authService: AuthService, ) { const cognitoAuthority = `https://cognito-idp.${CognitoAuthConfig.region}.amazonaws.com/${CognitoAuthConfig.userPoolId}`; From b5321ad71f3f158d1775d8669807f9ef2a2e5af8 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Fri, 23 Jan 2026 12:51:45 -0500 Subject: [PATCH 10/33] prettier --- apps/backend/src/auth/jwt.strategy.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index 295a132ad..b58a0a4da 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -9,9 +9,7 @@ import { User } from '../users/user.entity'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { - constructor( - private usersService: UsersService, - ) { + constructor(private usersService: UsersService) { const cognitoAuthority = `https://cognito-idp.${CognitoAuthConfig.region}.amazonaws.com/${CognitoAuthConfig.userPoolId}`; super({ From b61e462eff1c5f8689c94cb2d893c962fd06bdf2 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 25 Jan 2026 19:44:02 -0500 Subject: [PATCH 11/33] Added requested changes --- apps/backend/src/auth/jwt.strategy.ts | 2 +- .../src/pantries/pantries.controller.ts | 1 - package.json | 1 + yarn.lock | 25 ++++++++++++++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/backend/src/auth/jwt.strategy.ts b/apps/backend/src/auth/jwt.strategy.ts index b58a0a4da..906773f41 100644 --- a/apps/backend/src/auth/jwt.strategy.ts +++ b/apps/backend/src/auth/jwt.strategy.ts @@ -1,4 +1,4 @@ -import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { passportJwtSecret } from 'jwks-rsa'; import { ExtractJwt, Strategy } from 'passport-jwt'; diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index db30a244e..8961c9469 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -26,7 +26,6 @@ import { Order } from '../orders/order.entity'; import { OrdersService } from '../orders/order.service'; import { Public } from '../auth/public.decorator'; -@UseGuards(AuthGuard('jwt'), RolesGuard) @Controller('pantries') export class PantriesController { constructor( diff --git a/package.json b/package.json index f7d1e56ae..551234abc 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "@types/jest": "30.0.0", "@types/multer": "^1.4.12", "@types/node": "^18.14.2", + "@types/passport-jwt": "^4.0.1", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", "@typescript-eslint/eslint-plugin": "^8.23.0", diff --git a/yarn.lock b/yarn.lock index 31be72a16..1f59b7c08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5820,7 +5820,7 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/jsonwebtoken@^9.0.4": +"@types/jsonwebtoken@*", "@types/jsonwebtoken@^9.0.4": version "9.0.10" resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz#a7932a47177dcd4283b6146f3bd5c26d82647f09" integrity sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA== @@ -5869,6 +5869,29 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== +"@types/passport-jwt@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/passport-jwt/-/passport-jwt-4.0.1.tgz#080fbe934fb9f6954fb88ec4cdf4bb2cc7c4d435" + integrity sha512-Y0Ykz6nWP4jpxgEUYq8NoVZeCQPo1ZndJLfapI249g1jHChvRfZRO/LS3tqu26YgAS/laI1qx98sYGz0IalRXQ== + dependencies: + "@types/jsonwebtoken" "*" + "@types/passport-strategy" "*" + +"@types/passport-strategy@*": + version "0.2.38" + resolved "https://registry.yarnpkg.com/@types/passport-strategy/-/passport-strategy-0.2.38.tgz#482abba0b165cd4553ec8b748f30b022bd6c04d3" + integrity sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA== + dependencies: + "@types/express" "*" + "@types/passport" "*" + +"@types/passport@*": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.17.tgz#718a8d1f7000ebcf6bbc0853da1bc8c4bc7ea5e6" + integrity sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg== + dependencies: + "@types/express" "*" + "@types/prop-types@*": version "15.7.15" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" From dd41b4464fc91e0b7530b61cfadd7f24bcf678de Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 25 Jan 2026 23:48:00 -0500 Subject: [PATCH 12/33] Added in decorator and guard for a bypass gaurd --- apps/backend/src/app.module.ts | 4 ++++ apps/backend/src/pantries/pantries.controller.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/backend/src/app.module.ts b/apps/backend/src/app.module.ts index 7fe3ff82e..7a06f0d85 100644 --- a/apps/backend/src/app.module.ts +++ b/apps/backend/src/app.module.ts @@ -55,6 +55,10 @@ import { ScheduleModule } from '@nestjs/schedule'; provide: APP_GUARD, useClass: RolesGuard, }, + { + provide: APP_GUARD, + useClass: JwtAuthGuard, + } ], }) export class AppModule {} diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index 8961c9469..70cb632d8 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -33,7 +33,7 @@ export class PantriesController { private ordersService: OrdersService, ) {} - @Roles(Role.VOLUNTEER) + @Roles(Role.ADMIN) @Get('/pending') async getPendingPantries(): Promise { return this.pantriesService.getPendingPantries(); From 63a41a4a97d4527e170f788e233e901935857c49 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 25 Jan 2026 23:50:07 -0500 Subject: [PATCH 13/33] Final commit --- apps/backend/src/app.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/backend/src/app.module.ts b/apps/backend/src/app.module.ts index 7a06f0d85..fa5912ef0 100644 --- a/apps/backend/src/app.module.ts +++ b/apps/backend/src/app.module.ts @@ -58,7 +58,7 @@ import { ScheduleModule } from '@nestjs/schedule'; { provide: APP_GUARD, useClass: JwtAuthGuard, - } + }, ], }) export class AppModule {} From 396cc510a30daa532f5bfea5029a98eb5b23d04f Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Tue, 27 Jan 2026 20:54:45 -0500 Subject: [PATCH 14/33] Resolved comments --- .../donationItems/donationItems.controller.ts | 1 - .../interceptors/current-user.interceptor.ts | 29 +++++++++++++++++++ apps/frontend/src/api/apiClient.ts | 1 - 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 apps/backend/src/interceptors/current-user.interceptor.ts diff --git a/apps/backend/src/donationItems/donationItems.controller.ts b/apps/backend/src/donationItems/donationItems.controller.ts index bebe5c400..6435dd9ca 100644 --- a/apps/backend/src/donationItems/donationItems.controller.ts +++ b/apps/backend/src/donationItems/donationItems.controller.ts @@ -16,7 +16,6 @@ import { CreateMultipleDonationItemsDto } from './dtos/create-donation-items.dto @Controller('donation-items') //@UseInterceptors() -@UseGuards(AuthGuard('jwt')) export class DonationItemsController { constructor(private donationItemsService: DonationItemsService) {} diff --git a/apps/backend/src/interceptors/current-user.interceptor.ts b/apps/backend/src/interceptors/current-user.interceptor.ts new file mode 100644 index 000000000..53649fada --- /dev/null +++ b/apps/backend/src/interceptors/current-user.interceptor.ts @@ -0,0 +1,29 @@ +import { + Injectable, + NestInterceptor, + ExecutionContext, + CallHandler, +} from '@nestjs/common'; +import { AuthService } from '../auth/auth.service'; +import { UsersService } from '../users/users.service'; + +@Injectable() +export class CurrentUserInterceptor implements NestInterceptor { + constructor( + private authService: AuthService, + private usersService: UsersService, + ) {} + + async intercept(context: ExecutionContext, handler: CallHandler) { + const request = context.switchToHttp().getRequest(); + + if (request.user) { + const dbUser = await this.usersService.findUserByCognitoId( + request.user.sub, + ); + request.currentUser = dbUser; + } + + return handler.handle(); + } +} diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index b8b9369f1..09a317451 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -36,7 +36,6 @@ export class ApiClient { this.axiosInstance.interceptors.request.use( (config: InternalAxiosRequestConfig) => { const token = this.accessToken || localStorage.getItem('accessToken'); - console.log('Attaching token to request:', token); if (token) { config.headers = config.headers || {}; config.headers['Authorization'] = `Bearer ${token}`; From 7d9fc00972bc1dfb28bc7cbb1b3bf624838920a2 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Fri, 30 Jan 2026 14:49:34 -0500 Subject: [PATCH 15/33] Fixed addition of audience --- apps/backend/src/app.module.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/backend/src/app.module.ts b/apps/backend/src/app.module.ts index fa5912ef0..9509ea96b 100644 --- a/apps/backend/src/app.module.ts +++ b/apps/backend/src/app.module.ts @@ -53,12 +53,16 @@ import { ScheduleModule } from '@nestjs/schedule'; }, { provide: APP_GUARD, - useClass: RolesGuard, + useClass: JwtAuthGuard, }, { provide: APP_GUARD, useClass: JwtAuthGuard, }, + { + provide: APP_GUARD, + useClass: RolesGuard, + }, ], }) export class AppModule {} From 3f4a147a0816855e9fb7ec9b913dead3a6657862 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 1 Feb 2026 00:22:56 -0500 Subject: [PATCH 16/33] Fixed bugs wth id loader --- apps/frontend/src/containers/FormRequests.tsx | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/frontend/src/containers/FormRequests.tsx b/apps/frontend/src/containers/FormRequests.tsx index 479356e92..0f224c14f 100644 --- a/apps/frontend/src/containers/FormRequests.tsx +++ b/apps/frontend/src/containers/FormRequests.tsx @@ -20,6 +20,7 @@ import { OrderStatus, FoodRequest } from '../types/types'; import RequestDetailsModal from '@components/forms/requestDetailsModal'; import { formatDate } from '@utils/utils'; import ApiClient from '@api/apiClient'; +import { fetchAuthSession } from 'aws-amplify/auth'; const FormRequests: React.FC = () => { const [currentPage, setCurrentPage] = useState(1); @@ -42,6 +43,13 @@ const FormRequests: React.FC = () => { const fetchRequests = useCallback(async () => { if (pantryId) { try { + // Ensure we have the auth token before making the API call + const session = await fetchAuthSession(); + const idToken = session.tokens?.idToken?.toString(); + if (idToken) { + ApiClient.setAccessToken(idToken); + } + const data = await ApiClient.getPantryRequests(pantryId); const sortedData = data .slice() diff --git a/package.json b/package.json index 551234abc..d5f75f466 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@nestjs/typeorm": "^10.0.0", "@types/google-libphonenumber": "^7.4.30", "amazon-cognito-identity-js": "^6.3.5", - "aws-amplify": "^6.15.10", + "aws-amplify": "^6.16.0", "axios": "^1.8.2", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", From a300045e66925651bd8271111c3b4334484bcc84 Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 1 Feb 2026 00:35:58 -0500 Subject: [PATCH 17/33] Final commit --- apps/frontend/src/containers/FormRequests.tsx | 1 - apps/frontend/src/containers/landingPage.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/frontend/src/containers/FormRequests.tsx b/apps/frontend/src/containers/FormRequests.tsx index 0f224c14f..3abef943d 100644 --- a/apps/frontend/src/containers/FormRequests.tsx +++ b/apps/frontend/src/containers/FormRequests.tsx @@ -20,7 +20,6 @@ import { OrderStatus, FoodRequest } from '../types/types'; import RequestDetailsModal from '@components/forms/requestDetailsModal'; import { formatDate } from '@utils/utils'; import ApiClient from '@api/apiClient'; -import { fetchAuthSession } from 'aws-amplify/auth'; const FormRequests: React.FC = () => { const [currentPage, setCurrentPage] = useState(1); diff --git a/apps/frontend/src/containers/landingPage.tsx b/apps/frontend/src/containers/landingPage.tsx index 7ce581d6d..a46d6a226 100644 --- a/apps/frontend/src/containers/landingPage.tsx +++ b/apps/frontend/src/containers/landingPage.tsx @@ -11,4 +11,4 @@ const LandingPage: React.FC = () => { ); }; -export default LandingPage; +export default LandingPage; \ No newline at end of file From 9fe925541eefa9b69ea8a9f83081f24b5859a13e Mon Sep 17 00:00:00 2001 From: Dalton Burkhart Date: Sun, 1 Feb 2026 00:36:12 -0500 Subject: [PATCH 18/33] Final commit --- apps/frontend/src/containers/landingPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/containers/landingPage.tsx b/apps/frontend/src/containers/landingPage.tsx index a46d6a226..7ce581d6d 100644 --- a/apps/frontend/src/containers/landingPage.tsx +++ b/apps/frontend/src/containers/landingPage.tsx @@ -11,4 +11,4 @@ const LandingPage: React.FC = () => { ); }; -export default LandingPage; \ No newline at end of file +export default LandingPage; From 8c932c2b9d8ac15b0162dfe56bf362a5f1350035 Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Sun, 1 Feb 2026 23:00:59 -0500 Subject: [PATCH 19/33] remove ids from routes --- .../src/foodRequests/request.controller.ts | 5 +-- .../src/pantries/pantries.controller.spec.ts | 41 +++++++++++++++-- .../src/pantries/pantries.controller.ts | 14 ++++++ apps/backend/src/pantries/pantries.service.ts | 18 +++++++- apps/frontend/src/api/apiClient.ts | 9 +++- apps/frontend/src/app.tsx | 17 ++----- apps/frontend/src/containers/FormRequests.tsx | 30 ++++++++++--- .../src/containers/pantryDashboard.tsx | 45 +++++++++++-------- 8 files changed, 131 insertions(+), 48 deletions(-) diff --git a/apps/backend/src/foodRequests/request.controller.ts b/apps/backend/src/foodRequests/request.controller.ts index 714a37aee..230eb0c48 100644 --- a/apps/backend/src/foodRequests/request.controller.ts +++ b/apps/backend/src/foodRequests/request.controller.ts @@ -24,7 +24,6 @@ import { OrderStatus } from '../orders/types'; import { OrderDetailsDto } from './dtos/order-details.dto'; @Controller('requests') -// @UseInterceptors() export class RequestsController { constructor( private requestsService: RequestsService, @@ -41,14 +40,14 @@ export class RequestsController { } @Roles(Role.PANTRY, Role.ADMIN) - @Get('/get-all-requests/:pantryId') + @Get('/:pantryId/all') async getAllPantryRequests( @Param('pantryId', ParseIntPipe) pantryId: number, ): Promise { return this.requestsService.find(pantryId); } - @Get('/all-order-details/:requestId') + @Get('/:requestId/order-details') async getAllOrderDetailsFromRequest( @Param('requestId', ParseIntPipe) requestId: number, ): Promise { diff --git a/apps/backend/src/pantries/pantries.controller.spec.ts b/apps/backend/src/pantries/pantries.controller.spec.ts index c0d943328..63e02fe60 100644 --- a/apps/backend/src/pantries/pantries.controller.spec.ts +++ b/apps/backend/src/pantries/pantries.controller.spec.ts @@ -15,6 +15,8 @@ import { ServeAllergicChildren, } from './types'; import { ApplicationStatus } from '../shared/types'; +import { BadRequestException } from '@nestjs/common'; +import { User } from '../users/user.entity'; const mockPantriesService = mock(); const mockOrdersService = mock(); @@ -121,12 +123,24 @@ describe('PantriesController', () => { }); describe('getPantry', () => { - it('should return a single pantry by id', async () => { - mockPantriesService.findOne.mockResolvedValueOnce(mockPantry as Pantry); + it('should return a pantry by ID', async () => { + const mockUser: Partial = { + id: 1, + firstName: 'Test', + lastName: 'User', + email: 'test@test.com', + }; + const mockPantry: Partial = { + pantryId: 1, + pantryName: 'Test Pantry', + pantryUser: mockUser as User, + }; + + mockPantriesService.findOne.mockResolvedValue(mockPantry as Pantry); const result = await controller.getPantry(1); - - expect(result).toEqual(mockPantry as Pantry); + expect(result).toEqual(mockPantry); + expect(result.pantryUser).toEqual(mockUser); expect(mockPantriesService.findOne).toHaveBeenCalledWith(1); }); @@ -232,4 +246,23 @@ describe('PantriesController', () => { expect(mockOrdersService.getOrdersByPantry).toHaveBeenCalledWith(24); }); }); + + describe('getCurrentUserPantryId', () => { + it('returns pantryId when req.currentUser is present', async () => { + const req = { user: { id: 1 } }; + const pantry: Partial = { pantryId: 10 }; + mockPantriesService.findByUserId.mockResolvedValueOnce(pantry as Pantry); + + const result = await controller.getCurrentUserPantryId(req); + + expect(result).toEqual(10); + expect(mockPantriesService.findByUserId).toHaveBeenCalledWith(1); + }); + + it('throws BadRequestException when unauthenticated', async () => { + await expect(controller.getCurrentUserPantryId({})).rejects.toThrow( + new BadRequestException("Not authenticated") + ); + }); + }); }); diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index 70cb632d8..d0c261cf7 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -1,4 +1,5 @@ import { + BadRequestException, Body, Controller, Get, @@ -6,6 +7,7 @@ import { ParseIntPipe, Patch, Post, + Req, } from '@nestjs/common'; import { Pantry } from './pantries.entity'; import { PantriesService } from './pantries.service'; @@ -33,6 +35,18 @@ export class PantriesController { private ordersService: OrdersService, ) {} + @Roles(Role.PANTRY) + @Get('/my-id') + async getCurrentUserPantryId(@Req() req): Promise { + const currentUser = req.user; + if (!currentUser) { + throw new BadRequestException('Not authenticated'); + } + + const pantry = await this.pantriesService.findByUserId(currentUser.id); + return pantry.pantryId; + } + @Roles(Role.ADMIN) @Get('/pending') async getPendingPantries(): Promise { diff --git a/apps/backend/src/pantries/pantries.service.ts b/apps/backend/src/pantries/pantries.service.ts index 25dcca02b..e588f03f3 100644 --- a/apps/backend/src/pantries/pantries.service.ts +++ b/apps/backend/src/pantries/pantries.service.ts @@ -15,7 +15,10 @@ export class PantriesService { async findOne(pantryId: number): Promise { validateId(pantryId, 'Pantry'); - const pantry = await this.repo.findOne({ where: { pantryId } }); + const pantry = await this.repo.findOne({ + where: { pantryId }, + relations: ['pantryUser'], + }); if (!pantry) { throw new NotFoundException(`Pantry ${pantryId} not found`); @@ -125,4 +128,17 @@ export class PantriesService { return pantries; } + + async findByUserId(userId: number): Promise { + validateId(userId, 'User'); + + const pantry = await this.repo.findOne({ + where: { pantryUser: { id: userId } }, + }); + + if (!pantry) { + throw new NotFoundException(`Pantry for User ${userId} not found`); + } + return pantry; + } } diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index 09a317451..727ea4340 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -232,7 +232,7 @@ export class ApiClient { requestId: number, ): Promise { return this.axiosInstance - .get(`/api/requests/all-order-details/${requestId}`) + .get(`/api/requests/${requestId}/order-details`) .then((response) => response.data) as Promise; } @@ -262,7 +262,7 @@ export class ApiClient { } public async getPantryRequests(pantryId: number): Promise { - const data = await this.get(`/api/requests/get-all-requests/${pantryId}`); + const data = await this.get(`/api/requests/${pantryId}/all`); return data as FoodRequest[]; } @@ -286,6 +286,11 @@ export class ApiClient { alert(`Error submitting delivery confirmation: ${error}`); } } + + public async getCurrentUserPantryId(): Promise { + const data = await this.get('/api/pantries/my-id'); + return data as number; +} } export default new ApiClient(); diff --git a/apps/frontend/src/app.tsx b/apps/frontend/src/app.tsx index 62fb319d2..b2679176c 100644 --- a/apps/frontend/src/app.tsx +++ b/apps/frontend/src/app.tsx @@ -18,7 +18,6 @@ import VolunteerManagement from '@containers/volunteerManagement'; import FoodManufacturerOrderDashboard from '@containers/foodManufacturerOrderDashboard'; import DonationManagement from '@containers/donationManagement'; import AdminDonation from '@containers/adminDonation'; -import { pantryIdLoader } from '@loaders/pantryIdLoader'; import Homepage from '@containers/homepage'; import AdminOrderManagement from '@containers/adminOrderManagement'; import { Amplify } from 'aws-amplify'; @@ -81,14 +80,6 @@ const router = createBrowserRouter([ ), }, - { - path: '/pantry-dashboard/:pantryId', - element: ( - - - - ), - }, { path: '/pantry-past-orders', element: ( @@ -114,13 +105,12 @@ const router = createBrowserRouter([ ), }, { - path: '/pantry-dashboard/:pantryId', + path: '/pantry-dashboard', element: ( ), - loader: pantryIdLoader, }, { path: '/pantry-past-orders', @@ -155,13 +145,12 @@ const router = createBrowserRouter([ ), }, { - path: '/request-form/:pantryId', + path: '/request-form', element: ( - + ), - loader: pantryIdLoader, }, { path: '/donation-management', diff --git a/apps/frontend/src/containers/FormRequests.tsx b/apps/frontend/src/containers/FormRequests.tsx index 3abef943d..ed4a127e5 100644 --- a/apps/frontend/src/containers/FormRequests.tsx +++ b/apps/frontend/src/containers/FormRequests.tsx @@ -20,20 +20,23 @@ import { OrderStatus, FoodRequest } from '../types/types'; import RequestDetailsModal from '@components/forms/requestDetailsModal'; import { formatDate } from '@utils/utils'; import ApiClient from '@api/apiClient'; +import { useAuthenticator } from '@aws-amplify/ui-react'; const FormRequests: React.FC = () => { - const [currentPage, setCurrentPage] = useState(1); + const { user } = useAuthenticator((context) => [context.user]); const newRequestDisclosure = useDisclosure(); const previousRequestDisclosure = useDisclosure(); + const [pantryId, setPantryId] = useState(null); const [requests, setRequests] = useState([]); const [previousRequest, setPreviousRequest] = useState< FoodRequest | undefined >(undefined); - const { pantryId: pantryIdParam } = useParams<{ pantryId: string }>(); - const pantryId = parseInt(pantryIdParam!, 10); - + const [allConfirmed, setAllConfirmed] = useState(false); + const [openDeliveryRequestId, setOpenDeliveryRequestId] = useState< + number | null + >(null); const [openReadOnlyRequest, setOpenReadOnlyRequest] = useState(null); @@ -115,7 +118,7 @@ const FormRequests: React.FC = () => { previousRequest={previousRequest} isOpen={previousRequestDisclosure.open} onClose={previousRequestDisclosure.onClose} - pantryId={pantryId} + pantryId={pantryId!} onSuccess={fetchRequests} /> @@ -203,7 +206,22 @@ const FormRequests: React.FC = () => { request={openReadOnlyRequest} isOpen={openReadOnlyRequest !== null} onClose={() => setOpenReadOnlyRequest(null)} - pantryId={pantryId} + pantryId={pantryId!} + /> + )} + {openOrderId && ( + setOpenOrderId(null)} + /> + )} + {openDeliveryRequestId && ( + setOpenDeliveryRequestId(null)} + pantryId={pantryId!} /> )} diff --git a/apps/frontend/src/containers/pantryDashboard.tsx b/apps/frontend/src/containers/pantryDashboard.tsx index 39e98346a..b888ab9d4 100644 --- a/apps/frontend/src/containers/pantryDashboard.tsx +++ b/apps/frontend/src/containers/pantryDashboard.tsx @@ -12,34 +12,43 @@ import { } from '@chakra-ui/react'; import { MenuIcon } from 'lucide-react'; import React, { useEffect, useState } from 'react'; -import { User, Pantry } from 'types/types'; +import { Pantry } from 'types/types'; import ApiClient from '@api/apiClient'; -import { useParams } from 'react-router-dom'; +import { useAuthenticator } from '@aws-amplify/ui-react'; const PantryDashboard: React.FC = () => { - const [ssfRep, setSsfRep] = useState(null); + const { user } = useAuthenticator((context) => [context.user]); + const [pantryId, setPantryId] = useState(null); const [pantry, setPantry] = useState(null); - const { pantryId } = useParams<{ pantryId: string }>(); useEffect(() => { - if (!pantryId) { - console.error('Error: pantryId is undefined'); - return; - } - const fetchData = async () => { + const fetchPantryId = async () => { + if (user.userId) { + try { + const pantryId = await ApiClient.getCurrentUserPantryId(); + setPantryId(pantryId); + } catch (error) { + console.error('Error fetching pantry ID', error); + } + } + }; + + fetchPantryId(); + }, [user.userId]); + + useEffect(() => { + const fetchPantryData = async () => { + if (!pantryId) return; + try { - const [pantryData, ssfRepData] = await Promise.all([ - ApiClient.getPantry(parseInt(pantryId, 10)), - ApiClient.getPantrySSFRep(parseInt(pantryId, 10)), - ]); + const pantryData = await ApiClient.getPantry(pantryId); setPantry(pantryData); - setSsfRep(ssfRepData); } catch (error) { console.error('Error fetching pantry data/SSFRep data', error); } }; - fetchData(); + fetchPantryData(); }, [pantryId]); return ( @@ -116,9 +125,9 @@ const PantryDashboard: React.FC = () => { > Need help? Contact your SSF representative - Name: {ssfRep?.firstName} - Email: {ssfRep?.email} - Phone: {ssfRep?.phone} + Name: {pantry?.pantryUser?.firstName} {pantry?.pantryUser?.lastName} + Email: {pantry?.pantryUser?.email} + Phone: {pantry?.pantryUser?.phone} From d4059f99988f6f4de4dc002c0da7d3f8115b8652 Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Sun, 1 Feb 2026 23:01:31 -0500 Subject: [PATCH 20/33] prettier --- apps/backend/src/pantries/pantries.controller.spec.ts | 2 +- apps/backend/src/pantries/pantries.service.ts | 4 ++-- apps/frontend/src/api/apiClient.ts | 2 +- apps/frontend/src/containers/pantryDashboard.tsx | 4 +++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/backend/src/pantries/pantries.controller.spec.ts b/apps/backend/src/pantries/pantries.controller.spec.ts index 63e02fe60..045984684 100644 --- a/apps/backend/src/pantries/pantries.controller.spec.ts +++ b/apps/backend/src/pantries/pantries.controller.spec.ts @@ -261,7 +261,7 @@ describe('PantriesController', () => { it('throws BadRequestException when unauthenticated', async () => { await expect(controller.getCurrentUserPantryId({})).rejects.toThrow( - new BadRequestException("Not authenticated") + new BadRequestException('Not authenticated'), ); }); }); diff --git a/apps/backend/src/pantries/pantries.service.ts b/apps/backend/src/pantries/pantries.service.ts index e588f03f3..24238e927 100644 --- a/apps/backend/src/pantries/pantries.service.ts +++ b/apps/backend/src/pantries/pantries.service.ts @@ -15,9 +15,9 @@ export class PantriesService { async findOne(pantryId: number): Promise { validateId(pantryId, 'Pantry'); - const pantry = await this.repo.findOne({ + const pantry = await this.repo.findOne({ where: { pantryId }, - relations: ['pantryUser'], + relations: ['pantryUser'], }); if (!pantry) { diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index 727ea4340..f63a84f9f 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -290,7 +290,7 @@ export class ApiClient { public async getCurrentUserPantryId(): Promise { const data = await this.get('/api/pantries/my-id'); return data as number; -} + } } export default new ApiClient(); diff --git a/apps/frontend/src/containers/pantryDashboard.tsx b/apps/frontend/src/containers/pantryDashboard.tsx index b888ab9d4..dfc6329c0 100644 --- a/apps/frontend/src/containers/pantryDashboard.tsx +++ b/apps/frontend/src/containers/pantryDashboard.tsx @@ -125,7 +125,9 @@ const PantryDashboard: React.FC = () => { > Need help? Contact your SSF representative - Name: {pantry?.pantryUser?.firstName} {pantry?.pantryUser?.lastName} + + Name: {pantry?.pantryUser?.firstName} {pantry?.pantryUser?.lastName} + Email: {pantry?.pantryUser?.email} Phone: {pantry?.pantryUser?.phone} From bf7993ec8036a42515911194a16a8d5b66363a4f Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Sat, 14 Feb 2026 09:45:04 -0500 Subject: [PATCH 21/33] fix tests --- apps/backend/src/pantries/pantries.controller.ts | 16 ++-------------- .../src/pantries/pantries.service.spec.ts | 1 + 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index d0c261cf7..88ffdbbbc 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -54,16 +54,6 @@ export class PantriesController { } @Roles(Role.PANTRY, Role.ADMIN) - @UseGuards(RolesGuard) - @Get('/:pantryId/ssf-contact') - async getSSFRep( - @Param('pantryId', ParseIntPipe) pantryId: number, - ): Promise { - return this.pantriesService.findSSFRep(pantryId); - } - - @Roles(Role.PANTRY, Role.ADMIN) - @UseGuards(RolesGuard) @Get('/:pantryId') async getPantry( @Param('pantryId', ParseIntPipe) pantryId: number, @@ -324,8 +314,7 @@ export class PantriesController { } @Roles(Role.ADMIN) - @UseGuards(RolesGuard) - @Post('/approve/:pantryId') + @Patch('/:pantryId/approve') async approvePantry( @Param('pantryId', ParseIntPipe) pantryId: number, ): Promise { @@ -333,8 +322,7 @@ export class PantriesController { } @Roles(Role.ADMIN) - @UseGuards(RolesGuard) - @Post('/deny/:pantryId') + @Patch('/:pantryId/deny') async denyPantry( @Param('pantryId', ParseIntPipe) pantryId: number, ): Promise { diff --git a/apps/backend/src/pantries/pantries.service.spec.ts b/apps/backend/src/pantries/pantries.service.spec.ts index 2d7bdb14c..41ac7ffbf 100644 --- a/apps/backend/src/pantries/pantries.service.spec.ts +++ b/apps/backend/src/pantries/pantries.service.spec.ts @@ -103,6 +103,7 @@ describe('PantriesService', () => { expect(result).toBe(mockPendingPantry); expect(mockRepository.findOne).toHaveBeenCalledWith({ where: { pantryId: 1 }, + relations: ['pantryUser'], }); }); From 3d84e4bc44c9fd7989b7f3e02113a64d807e3bb3 Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Sat, 14 Feb 2026 09:49:55 -0500 Subject: [PATCH 22/33] fix form requests file --- apps/frontend/src/containers/FormRequests.tsx | 250 +++++++----------- 1 file changed, 101 insertions(+), 149 deletions(-) diff --git a/apps/frontend/src/containers/FormRequests.tsx b/apps/frontend/src/containers/FormRequests.tsx index ed4a127e5..0f39d7f34 100644 --- a/apps/frontend/src/containers/FormRequests.tsx +++ b/apps/frontend/src/containers/FormRequests.tsx @@ -1,24 +1,19 @@ import React, { useCallback, useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { - Box, + Center, Table, Text, Button, HStack, useDisclosure, - Link, - Badge, - Pagination, - ButtonGroup, - IconButton, - Flex, + NativeSelect, } from '@chakra-ui/react'; -import { ChevronRight, ChevronLeft } from 'lucide-react'; import FoodRequestFormModal from '@components/forms/requestFormModal'; -import { OrderStatus, FoodRequest } from '../types/types'; -import RequestDetailsModal from '@components/forms/requestDetailsModal'; -import { formatDate } from '@utils/utils'; +import DeliveryConfirmationModal from '@components/forms/deliveryConfirmationModal'; +import OrderInformationModal from '@components/forms/orderInformationModal'; +import { FoodRequest } from 'types/types'; +import { formatDate, formatReceivedDate } from '@utils/utils'; import ApiClient from '@api/apiClient'; import { useAuthenticator } from '@aws-amplify/ui-react'; @@ -32,6 +27,9 @@ const FormRequests: React.FC = () => { const [previousRequest, setPreviousRequest] = useState< FoodRequest | undefined >(undefined); + const [sortBy, setSortBy] = useState<'mostRecent' | 'oldest' | 'confirmed'>( + 'mostRecent', + ); const [allConfirmed, setAllConfirmed] = useState(false); const [openDeliveryRequestId, setOpenDeliveryRequestId] = useState< @@ -39,8 +37,7 @@ const FormRequests: React.FC = () => { >(null); const [openReadOnlyRequest, setOpenReadOnlyRequest] = useState(null); - - const pageSize = 10; + const [openOrderId, setOpenOrderId] = useState(null); const fetchRequests = useCallback(async () => { if (pantryId) { @@ -71,27 +68,33 @@ const FormRequests: React.FC = () => { fetchRequests(); }, [pantryId, fetchRequests]); - const paginatedRequests = requests.slice( - (currentPage - 1) * pageSize, - currentPage * pageSize, - ); + useEffect(() => { + setAllConfirmed(requests.every((request) => request.dateReceived !== null)); + }, [requests]); + + const sortedRequests = [...requests].sort((a, b) => { + if (sortBy === 'mostRecent') + return ( + new Date(b.requestedAt).getTime() - new Date(a.requestedAt).getTime() + ); + if (sortBy === 'oldest') + return ( + new Date(a.requestedAt).getTime() - new Date(b.requestedAt).getTime() + ); + if (sortBy === 'confirmed') + return ( + new Date(b.dateReceived || 0).getTime() - + new Date(a.dateReceived || 0).getTime() + ); + + return 0; + }); return ( - - - Food Request Management - - - { <> { )} - + + + + setSortBy(e.target.value as 'mostRecent' | 'oldest' | 'confirmed') + } + > + + + + + + + + - - Request # - - - Status - - - Date Requested - + Request ID + Order ID + Date Requested + Status + Shipped By + Date Fulfilled + Actions - {paginatedRequests.map((request) => ( + {sortedRequests.map((request) => ( - - setOpenReadOnlyRequest(request)} - > + + - {!request.orders || - request.orders.length === 0 || - request.orders.every( - (order) => - order.status === OrderStatus.PENDING || - order.status === OrderStatus.SHIPPED, - ) ? ( - + setOpenOrderId(request.orders?.[0]?.orderId ?? null) + } > - Active - + {request.orders?.[0]?.orderId} + ) : ( - - Closed - + 'N/A' )} - - {formatDate(request.requestedAt)} + {formatDate(request.requestedAt)} + + {request.orders?.[0]?.status ?? 'pending'} + + + {request.orders?.[0]?.status === 'pending' + ? 'N/A' + : request.orders?.[0]?.shippedBy ?? 'N/A'} + + + {formatReceivedDate(request.dateReceived)} + + + {!request.orders?.[0] || + request.orders?.[0]?.status === 'pending' ? ( + Awaiting Order Assignment + ) : request.orders?.[0]?.status === 'delivered' ? ( + Food Request is Already Delivered + ) : ( + + )} ))} {openReadOnlyRequest && ( - setOpenReadOnlyRequest(null)} pantryId={pantryId!} @@ -226,52 +222,8 @@ const FormRequests: React.FC = () => { )} - - setCurrentPage(page)} - > - - - setCurrentPage((prev) => Math.max(prev - 1, 1))} - > - - - - - ( - setCurrentPage(page.value)} - > - {page.value} - - )} - /> - - - - setCurrentPage((prev) => - Math.min(prev + 1, Math.ceil(requests.length / pageSize)), - ) - } - > - - - - - - - + ); }; -export default FormRequests; +export default FormRequests; \ No newline at end of file From 49a64e82a254b2636fda965eada82cf7062aa1a0 Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Sat, 14 Feb 2026 09:57:00 -0500 Subject: [PATCH 23/33] fix problems with merge --- apps/backend/src/app.module.ts | 8 ----- apps/backend/src/auth/auth.service.ts | 1 - apps/backend/src/auth/jwt.guard.ts | 5 ---- .../interceptors/current-user.interceptor.ts | 29 ------------------- apps/frontend/src/app.tsx | 2 +- apps/frontend/src/containers/FormRequests.tsx | 2 +- 6 files changed, 2 insertions(+), 45 deletions(-) delete mode 100644 apps/backend/src/auth/jwt.guard.ts delete mode 100644 apps/backend/src/interceptors/current-user.interceptor.ts diff --git a/apps/backend/src/app.module.ts b/apps/backend/src/app.module.ts index 9509ea96b..7fe3ff82e 100644 --- a/apps/backend/src/app.module.ts +++ b/apps/backend/src/app.module.ts @@ -51,14 +51,6 @@ import { ScheduleModule } from '@nestjs/schedule'; provide: APP_GUARD, useClass: JwtAuthGuard, }, - { - provide: APP_GUARD, - useClass: JwtAuthGuard, - }, - { - provide: APP_GUARD, - useClass: JwtAuthGuard, - }, { provide: APP_GUARD, useClass: RolesGuard, diff --git a/apps/backend/src/auth/auth.service.ts b/apps/backend/src/auth/auth.service.ts index 5ebb427e6..8c38f366e 100644 --- a/apps/backend/src/auth/auth.service.ts +++ b/apps/backend/src/auth/auth.service.ts @@ -6,7 +6,6 @@ import { ConfirmForgotPasswordCommand, ConfirmSignUpCommand, ForgotPasswordCommand, - ListUsersCommand, SignUpCommand, } from '@aws-sdk/client-cognito-identity-provider'; diff --git a/apps/backend/src/auth/jwt.guard.ts b/apps/backend/src/auth/jwt.guard.ts deleted file mode 100644 index f65f8455d..000000000 --- a/apps/backend/src/auth/jwt.guard.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; - -@Injectable() -export class JwtGuard extends AuthGuard('jwt') {} diff --git a/apps/backend/src/interceptors/current-user.interceptor.ts b/apps/backend/src/interceptors/current-user.interceptor.ts deleted file mode 100644 index 53649fada..000000000 --- a/apps/backend/src/interceptors/current-user.interceptor.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { - Injectable, - NestInterceptor, - ExecutionContext, - CallHandler, -} from '@nestjs/common'; -import { AuthService } from '../auth/auth.service'; -import { UsersService } from '../users/users.service'; - -@Injectable() -export class CurrentUserInterceptor implements NestInterceptor { - constructor( - private authService: AuthService, - private usersService: UsersService, - ) {} - - async intercept(context: ExecutionContext, handler: CallHandler) { - const request = context.switchToHttp().getRequest(); - - if (request.user) { - const dbUser = await this.usersService.findUserByCognitoId( - request.user.sub, - ); - request.currentUser = dbUser; - } - - return handler.handle(); - } -} diff --git a/apps/frontend/src/app.tsx b/apps/frontend/src/app.tsx index b2679176c..bd40e52db 100644 --- a/apps/frontend/src/app.tsx +++ b/apps/frontend/src/app.tsx @@ -149,7 +149,7 @@ const router = createBrowserRouter([ element: ( - + ), }, { diff --git a/apps/frontend/src/containers/FormRequests.tsx b/apps/frontend/src/containers/FormRequests.tsx index 0f39d7f34..def0f82b2 100644 --- a/apps/frontend/src/containers/FormRequests.tsx +++ b/apps/frontend/src/containers/FormRequests.tsx @@ -226,4 +226,4 @@ const FormRequests: React.FC = () => { ); }; -export default FormRequests; \ No newline at end of file +export default FormRequests; From 4a18517f86ef6a1a5d43e7c29b9be16c3170227a Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Sat, 14 Feb 2026 10:08:08 -0500 Subject: [PATCH 24/33] more cleanup --- apps/frontend/src/containers/pantryDashboard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/containers/pantryDashboard.tsx b/apps/frontend/src/containers/pantryDashboard.tsx index dfc6329c0..190dfea88 100644 --- a/apps/frontend/src/containers/pantryDashboard.tsx +++ b/apps/frontend/src/containers/pantryDashboard.tsx @@ -140,7 +140,7 @@ const PantryDashboard: React.FC = () => { _focus={{ textDecoration: 'none' }} textDecoration="none" > - + Request new shipment or check shipment status From 0ccaa38c78c586979001cae488189c20363e42ad Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Mon, 16 Feb 2026 13:20:54 -0500 Subject: [PATCH 25/33] review comments --- .../src/pantries/pantries.controller.ts | 4 +- .../src/pantries/pantries.service.spec.ts | 21 +++++ apps/frontend/src/app.tsx | 14 ++-- .../src/components/forms/requestFormModal.tsx | 31 +++++-- apps/frontend/src/containers/FormRequests.tsx | 83 +++++++++---------- 5 files changed, 97 insertions(+), 56 deletions(-) diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index 88ffdbbbc..8ed72be20 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -1,5 +1,4 @@ import { - BadRequestException, Body, Controller, Get, @@ -8,6 +7,7 @@ import { Patch, Post, Req, + UnauthorizedException, } from '@nestjs/common'; import { Pantry } from './pantries.entity'; import { PantriesService } from './pantries.service'; @@ -40,7 +40,7 @@ export class PantriesController { async getCurrentUserPantryId(@Req() req): Promise { const currentUser = req.user; if (!currentUser) { - throw new BadRequestException('Not authenticated'); + throw new UnauthorizedException('Not authenticated'); } const pantry = await this.pantriesService.findByUserId(currentUser.id); diff --git a/apps/backend/src/pantries/pantries.service.spec.ts b/apps/backend/src/pantries/pantries.service.spec.ts index 41ac7ffbf..52ab7bca5 100644 --- a/apps/backend/src/pantries/pantries.service.spec.ts +++ b/apps/backend/src/pantries/pantries.service.spec.ts @@ -281,4 +281,25 @@ describe('PantriesService', () => { expect(mockRepository.save).toHaveBeenCalled(); }); }); + + // TODO: once pantry service tests are fixed, uncomment this out + // describe('findByUserId', () => { + // it('should return a pantry by user id', async () => { + // const userId = 10; + // const pantry = await service.findByUserId(userId); + // console.log('Pantry found:', pantry); + + // expect(pantry.pantryId).toBe(1); + // expect(pantry.pantryName).toBe('Community Food Pantry Downtown'); + // expect(mockRepository.findOne).toHaveBeenCalledWith({ + // where: { pantryUser: { id: userId } }, + // }); + // }); + + // it('should throw NotFoundException if pantry not found', async () => { + // await expect(service.findByUserId(999)).rejects.toThrow( + // new NotFoundException('Pantry for User 999 not found'), + // ); + // }); + // }); }); diff --git a/apps/frontend/src/app.tsx b/apps/frontend/src/app.tsx index bd40e52db..e3abc7121 100644 --- a/apps/frontend/src/app.tsx +++ b/apps/frontend/src/app.tsx @@ -151,6 +151,7 @@ const router = createBrowserRouter([ ), + action: submitFoodRequestFormModal, }, { path: '/donation-management', @@ -160,6 +161,14 @@ const router = createBrowserRouter([ ), }, + { + path: '/donation-management', + element: ( + + + + ), + }, { path: '/approve-pantries', element: ( @@ -192,11 +201,6 @@ const router = createBrowserRouter([ ), }, - // Actions - { - path: '/food-request', - action: submitFoodRequestFormModal, - }, { path: '/confirm-delivery', action: submitDeliveryConfirmationFormModal, diff --git a/apps/frontend/src/components/forms/requestFormModal.tsx b/apps/frontend/src/components/forms/requestFormModal.tsx index 7f691fb80..fce0af128 100644 --- a/apps/frontend/src/components/forms/requestFormModal.tsx +++ b/apps/frontend/src/components/forms/requestFormModal.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from 'react'; +import { useActionData } from 'react-router-dom'; import { Flex, Button, @@ -39,6 +40,10 @@ const FoodRequestFormModal: React.FC = ({ const [requestedSize, setRequestedSize] = useState(''); const [additionalNotes, setAdditionalNotes] = useState(''); + const [alertMessage, setAlertMessage] = useState(''); + + const actionData = useActionData() as { error?: string; success?: boolean } | undefined; + const isFormValid = requestedSize !== '' && selectedItems.length > 0; useEffect(() => { @@ -52,6 +57,15 @@ const FoodRequestFormModal: React.FC = ({ } }, [isOpen, previousRequest]); + useEffect(() => { + if (actionData?.error) { + setAlertMessage(actionData.error); + } else if (actionData?.success) { + onClose(); + onSuccess(); + } + }, [actionData, onClose]); + const handleSubmit = async () => { const foodRequestData: CreateFoodRequestBody = { pantryId, @@ -63,12 +77,14 @@ const FoodRequestFormModal: React.FC = ({ photos: [], }; - try { + try { await apiClient.createFoodRequest(foodRequestData); - onClose(); - onSuccess(); - } catch (error) { - alert('Failed to submit request. Please try again.'); + return { success: true }; + } catch { + return { + error: 'Failed to submit food request', + success: false, + }; } }; @@ -81,6 +97,11 @@ const FoodRequestFormModal: React.FC = ({ }} closeOnInteractOutside > + {alertMessage && ( + // TODO: add Justin's alert component/uncomment below out and remove text component + // + {alertMessage} + )} diff --git a/apps/frontend/src/containers/FormRequests.tsx b/apps/frontend/src/containers/FormRequests.tsx index def0f82b2..94688b0c6 100644 --- a/apps/frontend/src/containers/FormRequests.tsx +++ b/apps/frontend/src/containers/FormRequests.tsx @@ -1,5 +1,4 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; import { Center, Table, @@ -40,33 +39,31 @@ const FormRequests: React.FC = () => { const [openOrderId, setOpenOrderId] = useState(null); const fetchRequests = useCallback(async () => { - if (pantryId) { - try { - // Ensure we have the auth token before making the API call - const session = await fetchAuthSession(); - const idToken = session.tokens?.idToken?.toString(); - if (idToken) { - ApiClient.setAccessToken(idToken); - } - - const data = await ApiClient.getPantryRequests(pantryId); - const sortedData = data - .slice() - .sort((a, b) => b.requestId - a.requestId); - setRequests(sortedData); + if (user.userId) { + const pantryId = await ApiClient.getCurrentUserPantryId(); + setPantryId(pantryId); + if (pantryId) { + try { + const data = await ApiClient.getPantryRequests(pantryId); + setRequests(data); - if (sortedData.length > 0) { - setPreviousRequest(sortedData[0]); + if (data.length > 0) { + setPreviousRequest( + data.reduce((prev, current) => + prev.requestId > current.requestId ? prev : current, + ), + ); + } + } catch (error) { + console.log(error); } - } catch (error) { - console.log(error); } } - }, [pantryId]); + }, [user.userId]); useEffect(() => { fetchRequests(); - }, [pantryId, fetchRequests]); + }, [user.userId, fetchRequests]); useEffect(() => { setAllConfirmed(requests.every((request) => request.dateReceived !== null)); @@ -96,13 +93,15 @@ const FormRequests: React.FC = () => { - + {pantryId && ( + + )} {previousRequest && ( <> - + )} )} @@ -143,7 +144,6 @@ const FormRequests: React.FC = () => { Order ID Date Requested Status - Shipped By Date Fulfilled Actions @@ -173,11 +173,6 @@ const FormRequests: React.FC = () => { {request.orders?.[0]?.status ?? 'pending'} - - {request.orders?.[0]?.status === 'pending' - ? 'N/A' - : request.orders?.[0]?.shippedBy ?? 'N/A'} - {formatReceivedDate(request.dateReceived)} @@ -197,12 +192,12 @@ const FormRequests: React.FC = () => { ))} - {openReadOnlyRequest && ( + {openReadOnlyRequest && pantryId && ( setOpenReadOnlyRequest(null)} - pantryId={pantryId!} + pantryId={pantryId} /> )} {openOrderId && ( @@ -212,12 +207,12 @@ const FormRequests: React.FC = () => { onClose={() => setOpenOrderId(null)} /> )} - {openDeliveryRequestId && ( + {openDeliveryRequestId && pantryId && ( setOpenDeliveryRequestId(null)} - pantryId={pantryId!} + pantryId={pantryId} /> )} From c05987c40dbf31c1f2398a7b11efe622ae20a0b5 Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Mon, 16 Feb 2026 13:28:26 -0500 Subject: [PATCH 26/33] add exception propagation test --- .../src/pantries/pantries.controller.spec.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/backend/src/pantries/pantries.controller.spec.ts b/apps/backend/src/pantries/pantries.controller.spec.ts index 045984684..063943f36 100644 --- a/apps/backend/src/pantries/pantries.controller.spec.ts +++ b/apps/backend/src/pantries/pantries.controller.spec.ts @@ -15,7 +15,7 @@ import { ServeAllergicChildren, } from './types'; import { ApplicationStatus } from '../shared/types'; -import { BadRequestException } from '@nestjs/common'; +import { BadRequestException, NotFoundException } from '@nestjs/common'; import { User } from '../users/user.entity'; const mockPantriesService = mock(); @@ -264,5 +264,17 @@ describe('PantriesController', () => { new BadRequestException('Not authenticated'), ); }); + + it('propagates NotFoundException from service', async () => { + const req = { user: { id: 999 } }; + mockPantriesService.findByUserId.mockRejectedValueOnce( + new NotFoundException('Pantry for User 999 not found'), + ); + + const promise = controller.getCurrentUserPantryId(req); + await expect(promise).rejects.toBeInstanceOf(NotFoundException); + await expect(promise).rejects.toThrow('Pantry for User 999 not found'); + expect(mockPantriesService.findByUserId).toHaveBeenCalledWith(999); + }); }); }); From f30cd5828ceca49316885789360da80971e78241 Mon Sep 17 00:00:00 2001 From: Justin Wang <74576640+Juwang110@users.noreply.github.com> Date: Mon, 16 Feb 2026 17:32:59 -0500 Subject: [PATCH 27/33] SSF-122 auth page frontend (#94) * login page * signup page * forgot password flow * refactoring to use my login page instead of authenticator from amplify * refactoring to combine verification and new password modals * minor refactoring * prettier * minor refactoring * switching button color to ssf blue * minor refactoring * adding password requirement info and eye crossed out icon * changing password requirement text to be accurate * making all routes protected, refactoring password requirement visual * adding alert for password being 8 characters at least --- apps/frontend/src/app.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/app.tsx b/apps/frontend/src/app.tsx index e3abc7121..9e4fe7c1b 100644 --- a/apps/frontend/src/app.tsx +++ b/apps/frontend/src/app.tsx @@ -162,7 +162,7 @@ const router = createBrowserRouter([ ), }, { - path: '/donation-management', + path: '/approve-pantries', element: ( From 48148896776e672ddaaf51064ba1bce8531c356c Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Tue, 17 Feb 2026 11:59:54 -0500 Subject: [PATCH 28/33] review comments --- apps/frontend/src/api/apiClient.ts | 2 +- .../src/components/forms/deliveryConfirmationModal.tsx | 3 +-- apps/frontend/src/containers/homepage.tsx | 8 ++------ apps/frontend/src/containers/pantryDashboard.tsx | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index f63a84f9f..5c112824e 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -278,7 +278,7 @@ export class ApiClient { if (response.status === 200) { alert('Delivery confirmation submitted successfully'); - window.location.href = '/request-form/1'; + window.location.href = '/request-form'; } else { alert(`Failed to submit: ${response.statusText}`); } diff --git a/apps/frontend/src/components/forms/deliveryConfirmationModal.tsx b/apps/frontend/src/components/forms/deliveryConfirmationModal.tsx index c85b09cfe..03a6a66e5 100644 --- a/apps/frontend/src/components/forms/deliveryConfirmationModal.tsx +++ b/apps/frontend/src/components/forms/deliveryConfirmationModal.tsx @@ -177,11 +177,10 @@ export const submitDeliveryConfirmationFormModal: ActionFunction = async ({ confirmDeliveryData, ); alert('Delivery confirmation submitted successfully'); - window.location.href = `/request-form/${pantryId}`; } catch (error) { alert(`Error submitting delivery confirmation: ${error}`); - window.location.href = `/request-form/${pantryId}`; } + window.location.href = '/request-form'; }; export default DeliveryConfirmationModal; diff --git a/apps/frontend/src/containers/homepage.tsx b/apps/frontend/src/containers/homepage.tsx index a7d784410..ba539a5f1 100644 --- a/apps/frontend/src/containers/homepage.tsx +++ b/apps/frontend/src/containers/homepage.tsx @@ -32,9 +32,7 @@ const Homepage: React.FC = () => { - - Pantry Dashboard (ID: 1) - + Pantry Dashboard @@ -44,9 +42,7 @@ const Homepage: React.FC = () => { - - Request Form (Pantry ID: 1) - + Request Form diff --git a/apps/frontend/src/containers/pantryDashboard.tsx b/apps/frontend/src/containers/pantryDashboard.tsx index 190dfea88..a5bc636b1 100644 --- a/apps/frontend/src/containers/pantryDashboard.tsx +++ b/apps/frontend/src/containers/pantryDashboard.tsx @@ -93,7 +93,7 @@ const PantryDashboard: React.FC = () => { From 5c5828c1958bce5feaa74d0b1aaa7e7897147ea7 Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:04:44 -0500 Subject: [PATCH 29/33] fix error --- apps/frontend/src/api/apiClient.ts | 3 +- .../forms/pantryApplicationForm.tsx | 4 +- .../src/components/forms/requestFormModal.tsx | 53 ++++++++++--------- apps/frontend/src/containers/FormRequests.tsx | 2 +- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/apps/frontend/src/api/apiClient.ts b/apps/frontend/src/api/apiClient.ts index 5c112824e..770db8750 100644 --- a/apps/frontend/src/api/apiClient.ts +++ b/apps/frontend/src/api/apiClient.ts @@ -178,8 +178,7 @@ export class ApiClient { body: { role: string }, ): Promise { return this.axiosInstance - .put(`/api/users/${userId}/role`, body) - .then(() => {}); + .put(`/api/users/${userId}/role`, body); } public async getOrderFoodRequest(requestId: number): Promise { diff --git a/apps/frontend/src/components/forms/pantryApplicationForm.tsx b/apps/frontend/src/components/forms/pantryApplicationForm.tsx index a132376da..0c831b9d0 100644 --- a/apps/frontend/src/components/forms/pantryApplicationForm.tsx +++ b/apps/frontend/src/components/forms/pantryApplicationForm.tsx @@ -70,7 +70,7 @@ const PantryApplicationForm: React.FC = () => { const [secondaryContactPhone, setSecondaryContactPhone] = useState(''); const [activities, setActivities] = useState([]); - const allergenClientsExactOption: string = 'I have an exact number'; + const allergenClientsExactOption = 'I have an exact number'; const [allergenClients, setAllergenClients] = useState(); const [restrictions, setRestrictions] = useState([]); @@ -1226,7 +1226,7 @@ export const submitPantryApplicationForm: ActionFunction = async ({ const data = Object.fromEntries(pantryApplicationData); - let submissionSuccessful: boolean = false; + let submissionSuccessful = false; await ApiClient.postPantry(data as PantryApplicationDto).then( () => (submissionSuccessful = true), diff --git a/apps/frontend/src/components/forms/requestFormModal.tsx b/apps/frontend/src/components/forms/requestFormModal.tsx index fce0af128..b1822b2d4 100644 --- a/apps/frontend/src/components/forms/requestFormModal.tsx +++ b/apps/frontend/src/components/forms/requestFormModal.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { useActionData } from 'react-router-dom'; +import { ActionFunction, ActionFunctionArgs, useActionData } from 'react-router-dom'; import { Flex, Button, @@ -66,28 +66,6 @@ const FoodRequestFormModal: React.FC = ({ } }, [actionData, onClose]); - const handleSubmit = async () => { - const foodRequestData: CreateFoodRequestBody = { - pantryId, - requestedSize: requestedSize as RequestSize, - requestedItems: selectedItems, - additionalInformation: additionalNotes || '', - dateReceived: null, - feedback: null, - photos: [], - }; - - try { - await apiClient.createFoodRequest(foodRequestData); - return { success: true }; - } catch { - return { - error: 'Failed to submit food request', - success: false, - }; - } - }; - return ( = ({ - {pantryId && ( - - )} + {previousRequest && ( <> {pantryId && ( { )} - - - - setSortBy(e.target.value as 'mostRecent' | 'oldest' | 'confirmed') - } - > - - - - - - - - + - Request ID - Order ID - Date Requested - Status - Date Fulfilled - Actions + + Request # + + + Status + + + Date Requested + - {sortedRequests.map((request) => ( + {paginatedRequests.map((request) => ( - - + - {request.orders?.[0]?.orderId ? ( - - ) : ( - 'N/A' - )} - - {formatDate(request.requestedAt)} - - {request.orders?.[0]?.status ?? 'pending'} - - - {formatReceivedDate(request.dateReceived)} - - - {!request.orders?.[0] || - request.orders?.[0]?.status === 'pending' ? ( - Awaiting Order Assignment - ) : request.orders?.[0]?.status === 'delivered' ? ( - Food Request is Already Delivered + Active + ) : ( - + Closed + )} + + {formatDate(request.requestedAt)} + ))} {openReadOnlyRequest && pantryId && ( - setOpenReadOnlyRequest(null)} pantryId={pantryId} /> )} - {openOrderId && ( - setOpenOrderId(null)} - /> - )} - {openDeliveryRequestId && pantryId && ( - setOpenDeliveryRequestId(null)} - pantryId={pantryId} - /> - )} - + + setCurrentPage(page)} + > + + + setCurrentPage((prev) => Math.max(prev - 1, 1))} + > + + + + + ( + setCurrentPage(page.value)} + > + {page.value} + + )} + /> + + + + setCurrentPage((prev) => + Math.min(prev + 1, Math.ceil(requests.length / pageSize)), + ) + } + > + + + + + + + ); }; From 1eefd3faa05fcb9c0a7e427adc588c6c887f89dc Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:30:42 -0500 Subject: [PATCH 32/33] clean up --- apps/frontend/src/components/forms/requestFormModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/components/forms/requestFormModal.tsx b/apps/frontend/src/components/forms/requestFormModal.tsx index d7bf36c8d..3c4974d6d 100644 --- a/apps/frontend/src/components/forms/requestFormModal.tsx +++ b/apps/frontend/src/components/forms/requestFormModal.tsx @@ -57,7 +57,7 @@ const FoodRequestFormModal: React.FC = ({ const handleSubmit = async () => { const foodRequestData: CreateFoodRequestBody = { - pantryId: pantryId, + pantryId, requestedSize: requestedSize as RequestSize, additionalInformation: additionalNotes || '', requestedItems: selectedItems, From 8cea3808707d1a1f12fea7fba343dbbf5d7bbefe Mon Sep 17 00:00:00 2001 From: amywng <147568742+amywng@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:34:16 -0500 Subject: [PATCH 33/33] fix yarnfile --- yarn.lock | 126 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 51 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1f59b7c08..295bbb82a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -348,9 +348,9 @@ tslib "^1.11.1" "@aws-sdk/client-cognito-identity-provider@^3.410.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.990.0.tgz#2a7ea55510da6b04777dc590b851b83dcc59bbca" - integrity sha512-9kiWFZGalAnZ+eyg6LP8ZUYLM/JEBvDcwOBRDDEqp7sp+iNWLF8ckbP5FPNZH5OD9Ci1EQyfLm6yu7caVUlxnA== + version "3.992.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.992.0.tgz#293314db5bea2e35ca504196f29ba7864b9d66eb" + integrity sha512-i44cLvuFhcn8qHzMi95iCDlncl2So3ZtUb0NIok8pyr0VUfkpSDH0VxdJJz0YX8C7xCufH2EUUDxJjLdOYqIJQ== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" @@ -362,7 +362,7 @@ "@aws-sdk/middleware-user-agent" "^3.972.10" "@aws-sdk/region-config-resolver" "^3.972.3" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.990.0" + "@aws-sdk/util-endpoints" "3.992.0" "@aws-sdk/util-user-agent-browser" "^3.972.3" "@aws-sdk/util-user-agent-node" "^3.972.8" "@smithy/config-resolver" "^4.4.6" @@ -532,9 +532,9 @@ tslib "^2.6.2" "@aws-sdk/client-s3@^3.735.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.990.0.tgz#5cafb93eba5e8fd26e16a6f7fc27776a85d08878" - integrity sha512-XnsM8RgB35Atn2+aYSocitCybDG82x9yYf/s2D23ytpyHCupmuZN3LzK2a0WxmKO6Zf7EtEIYy0mHGY4tLp9YA== + version "3.992.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.992.0.tgz#27908fd00ee0597140d2f6d052d3dac65b9aca40" + integrity sha512-6xfXGCvnWGgy5zZAse64Ru2G2qLKnPY7h8tchlsmGWVcJOWgz7iM3jmsWsQiJ79zH9A8HAPHU+ZD8TYYkwC+0Q== dependencies: "@aws-crypto/sha1-browser" "5.2.0" "@aws-crypto/sha256-browser" "5.2.0" @@ -552,9 +552,9 @@ "@aws-sdk/middleware-ssec" "^3.972.3" "@aws-sdk/middleware-user-agent" "^3.972.10" "@aws-sdk/region-config-resolver" "^3.972.3" - "@aws-sdk/signature-v4-multi-region" "3.990.0" + "@aws-sdk/signature-v4-multi-region" "3.992.0" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.990.0" + "@aws-sdk/util-endpoints" "3.992.0" "@aws-sdk/util-user-agent-browser" "^3.972.3" "@aws-sdk/util-user-agent-node" "^3.972.8" "@smithy/config-resolver" "^4.4.6" @@ -782,9 +782,9 @@ tslib "^2.6.2" "@aws-sdk/lib-storage@^3.735.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.990.0.tgz#d5b19c4531b5267f1c06078874c789c67971cce3" - integrity sha512-SHog6kMWXwLBTeVwFAd+EHwr1874Ei5ob1DTL5mLmJDwbmkFog2VDKN+9BmI4di0yxY057Ps2vhhWLhKy89wuA== + version "3.992.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.992.0.tgz#70b7a6f5340d65f6d6360ae00811fb81b73dff0b" + integrity sha512-XMbA5Sscho56oMNZi9G3LJirZqazpOlQvcGWoH1UvF1PN3iiYpO1l2g84LH9Xju1yU3BiLaxukEzD5aKyrPp0w== dependencies: "@smithy/abort-controller" "^4.2.8" "@smithy/middleware-endpoint" "^4.4.14" @@ -973,10 +973,10 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/signature-v4-multi-region@3.990.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.990.0.tgz#3ab40960673058f826ffbbe45bc8d354c5e31c0d" - integrity sha512-O55s1eFmKi+2Ko5T1hbdxL6tFVONGscSVe9VRxS4m91Tlbo9iG2Q2HvKWq1DuKQAuUWSUfMmjrRt07JNzizr2A== +"@aws-sdk/signature-v4-multi-region@3.992.0": + version "3.992.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.992.0.tgz#a2875715201005cdcbf47d36ecdfe38d76d95f7d" + integrity sha512-jWoaM89xH2cYOY6O+PWMa0yqjzKlE61Ehea1hJe34kHg9QvZOkcSA5OT9CNaFXsAvafeAAHBhSE8XlDiNaJFuw== dependencies: "@aws-sdk/middleware-sdk-s3" "^3.972.10" "@aws-sdk/types" "^3.973.1" @@ -1035,6 +1035,17 @@ "@smithy/util-endpoints" "^3.2.8" tslib "^2.6.2" +"@aws-sdk/util-endpoints@3.992.0": + version "3.992.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.992.0.tgz#cfba9509156c124663203a8536bef18b7f81b37b" + integrity sha512-FHgdMVbTZ2Lu7hEIoGYfkd5UazNSsAgPcupEnh15vsWKFKhuw6w/6tM1k/yNaa7l1wx0Wt1UuK0m+gQ0BJpuvg== + dependencies: + "@aws-sdk/types" "^3.973.1" + "@smithy/types" "^4.12.0" + "@smithy/url-parser" "^4.2.8" + "@smithy/util-endpoints" "^3.2.8" + tslib "^2.6.2" + "@aws-sdk/util-locate-window@^3.0.0": version "3.965.4" resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.965.4.tgz#f62d279e1905f6939b6dffb0f76ab925440f72bf" @@ -4913,10 +4924,10 @@ "@smithy/util-middleware" "^4.2.8" tslib "^2.6.2" -"@smithy/core@^3.22.0", "@smithy/core@^3.23.0": - version "3.23.0" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.23.0.tgz#64dca2825753316ace7b8342cb96c9dfc5de4e2a" - integrity sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg== +"@smithy/core@^3.22.0", "@smithy/core@^3.23.0", "@smithy/core@^3.23.1": + version "3.23.1" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.23.1.tgz#d3d30e1111093f4833435416bf7daac4eab3b0d3" + integrity sha512-F6nYWvsF0EUYo3Ge1+RWajbhfM9EkCoiZkDQNMrqsOSTZsgNfxjg4FZzFaEBlT0Oex6Fwt7HkRoQH2B9gGQZSw== dependencies: "@smithy/middleware-serde" "^4.2.9" "@smithy/protocol-http" "^5.3.8" @@ -5081,12 +5092,12 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@smithy/middleware-endpoint@^4.4.12", "@smithy/middleware-endpoint@^4.4.14": - version "4.4.14" - resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.14.tgz#df8aca71af70366f39305eeaf18ffd650f764219" - integrity sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag== +"@smithy/middleware-endpoint@^4.4.12", "@smithy/middleware-endpoint@^4.4.14", "@smithy/middleware-endpoint@^4.4.15": + version "4.4.15" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.15.tgz#dee18a3c23da7b81c88bcd794a7f4445f8c6f6c3" + integrity sha512-XPt69QTK5267KxXnX0Lu5zFAYiwoqTnM5HiMmosFg43A9Enoao75fXw9Qvie/3oWbEZmSMqELfUBsphRJ3C0XQ== dependencies: - "@smithy/core" "^3.23.0" + "@smithy/core" "^3.23.1" "@smithy/middleware-serde" "^4.2.9" "@smithy/node-config-provider" "^4.3.8" "@smithy/shared-ini-file-loader" "^4.4.3" @@ -5096,14 +5107,14 @@ tslib "^2.6.2" "@smithy/middleware-retry@^4.4.29", "@smithy/middleware-retry@^4.4.31": - version "4.4.31" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.4.31.tgz#1dbdbaedbd62f4900e3520f65599810123c0c461" - integrity sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg== + version "4.4.32" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.4.32.tgz#3aed77456028de227abe9a77516e2633300f4f48" + integrity sha512-SzklZYMxHp5Rqghah7eFKlAbaMMa72+WZeMJZFmdcjipM+QWwIWIHprJnGdRlK6bpvfDvEB4JrVa4vPWz4BE5w== dependencies: "@smithy/node-config-provider" "^4.3.8" "@smithy/protocol-http" "^5.3.8" "@smithy/service-error-classification" "^4.2.8" - "@smithy/smithy-client" "^4.11.3" + "@smithy/smithy-client" "^4.11.4" "@smithy/types" "^4.12.0" "@smithy/util-middleware" "^4.2.8" "@smithy/util-retry" "^4.2.8" @@ -5210,13 +5221,13 @@ "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" -"@smithy/smithy-client@^4.11.1", "@smithy/smithy-client@^4.11.3": - version "4.11.3" - resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.11.3.tgz#94d1083d5bc3b09e510f680ad7f82395765badf3" - integrity sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg== +"@smithy/smithy-client@^4.11.1", "@smithy/smithy-client@^4.11.3", "@smithy/smithy-client@^4.11.4": + version "4.11.4" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.11.4.tgz#c78bb5f3393063d8f6b4cd6516ad0942aa673387" + integrity sha512-Cs+Hwj4vAn6bHnLflSfgV6q9shkXUWAHcwgcVQ7Ez5v7YrINuIGfCfp0NBqh+lYUgLriCW5RjhF6Z6x8vgFYRQ== dependencies: - "@smithy/core" "^3.23.0" - "@smithy/middleware-endpoint" "^4.4.14" + "@smithy/core" "^3.23.1" + "@smithy/middleware-endpoint" "^4.4.15" "@smithy/middleware-stack" "^4.2.8" "@smithy/protocol-http" "^5.3.8" "@smithy/types" "^4.12.0" @@ -5317,25 +5328,25 @@ tslib "^2.6.2" "@smithy/util-defaults-mode-browser@^4.3.28", "@smithy/util-defaults-mode-browser@^4.3.30": - version "4.3.30" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.30.tgz#0494c467897ddf5b09b6f87712992b7b0ebe1cc1" - integrity sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng== + version "4.3.31" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.31.tgz#e2337c476189abfcd9b22025ccdbed99b4bf903d" + integrity sha512-76fzZbPajGAtCjMbWaFmxLYxRtLkZSYNG8drOjZU9Y0TJIPxaQwg8/JiQNLLPezmK0GTiglzki7Go+oTG0NMAw== dependencies: "@smithy/property-provider" "^4.2.8" - "@smithy/smithy-client" "^4.11.3" + "@smithy/smithy-client" "^4.11.4" "@smithy/types" "^4.12.0" tslib "^2.6.2" "@smithy/util-defaults-mode-node@^4.2.31", "@smithy/util-defaults-mode-node@^4.2.33": - version "4.2.33" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.33.tgz#b5d8b88d398d4556fe3e6299d7a14eac2b892750" - integrity sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA== + version "4.2.34" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.34.tgz#c0b61f1ea01006df56150286e686cfd80058960f" + integrity sha512-mhT5F2nwA9OHmdkQu+r2GKLMAmE3ht8rBWHLGo5i8acRRVo9XUrqN2nxI2f6yRyw8e7hZ2TCqNRVOJk9VUWyhQ== dependencies: "@smithy/config-resolver" "^4.4.6" "@smithy/credential-provider-imds" "^4.2.8" "@smithy/node-config-provider" "^4.3.8" "@smithy/property-provider" "^4.2.8" - "@smithy/smithy-client" "^4.11.3" + "@smithy/smithy-client" "^4.11.4" "@smithy/types" "^4.12.0" tslib "^2.6.2" @@ -7707,7 +7718,7 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-amplify@^6.15.10: +aws-amplify@^6.16.0: version "6.16.2" resolved "https://registry.yarnpkg.com/aws-amplify/-/aws-amplify-6.16.2.tgz#24e88c16d7020d26fa11d9c934b9b1e26a3d71cc" integrity sha512-7CHwfH5QxZ0rzCws/DNy5VLVcIIZWd9iUTtV1Oj6kPzpkFhCJ2I8gTvhFdh61HLhrg2lShcPQ8cecBIQS/ZJ0A== @@ -12491,9 +12502,9 @@ levn@^0.4.1: type-check "~0.4.0" libphonenumber-js@^1.11.1: - version "1.12.36" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.36.tgz#3698ba31e77fc4e5d4e3257dedc76f28cb594c35" - integrity sha512-woWhKMAVx1fzzUnMCyOzglgSgf6/AFHLASdOBcchYCyvWSGWt12imw3iu2hdI5d4dGZRsNWAmWiz37sDKUPaRQ== + version "1.12.37" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.37.tgz#a60e3f14ce79f5df4c9a16bede3608d3eab37a5f" + integrity sha512-rDU6bkpuMs8YRt/UpkuYEAsYSoNuDEbrE41I3KNvmXREGH6DGBJ8Wbak4by29wNOQ27zk4g4HL82zf0OGhwRuw== license-webpack-plugin@^4.0.2: version "4.0.2" @@ -13164,6 +13175,16 @@ node-emoji@1.11.0: dependencies: lodash "^4.17.21" +node-exports-info@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/node-exports-info/-/node-exports-info-1.6.0.tgz#1aedafb01a966059c9a5e791a94a94d93f5c2a13" + integrity sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw== + dependencies: + array.prototype.flatmap "^1.3.3" + es-errors "^1.3.0" + object.entries "^1.1.9" + semver "^6.3.1" + node-fetch@2.7.0, node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -14614,11 +14635,14 @@ resolve@^1.1.7, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.22.11, resolve@^1.2 supports-preserve-symlinks-flag "^1.0.0" resolve@^2.0.0-next.5: - version "2.0.0-next.5" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" - integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + version "2.0.0-next.6" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.6.tgz#b3961812be69ace7b3bc35d5bf259434681294af" + integrity sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA== dependencies: - is-core-module "^2.13.0" + es-errors "^1.3.0" + is-core-module "^2.16.1" + node-exports-info "^1.6.0" + object-keys "^1.1.1" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0"