Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/backend/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { AuthService } from './auth.service';
import { UsersService } from '../users/users.service';
import { VerifyUserDto } from './dtos/verify-user.dto';
import { DeleteUserDto } from './dtos/delete-user.dto';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { SignInResponseDto } from './dtos/sign-in-response.dto';
import { RefreshTokenDto } from './dtos/refresh-token.dto';
import { ConfirmPasswordDto } from './dtos/confirm-password.dto';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/authenticated-request.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request } from 'express';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';

// user does not have to be provided by the client but is added automatically by the auth backend
export interface AuthenticatedRequest extends Request {
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/jwt.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ExtractJwt, Strategy } from 'passport-jwt';
import { UsersService } from '../users/users.service';
import CognitoAuthConfig from './aws-exports';
import { CognitoJwtPayload } from './jwt-payload.interface';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/config/typeormTestDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DataSource, DataSourceOptions } from 'typeorm';
import { PluralNamingStrategy } from '../strategies/plural-naming.strategy';
import { Order } from '../orders/order.entity';
import { Pantry } from '../pantries/pantries.entity';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { Donation } from '../donations/donations.entity';
import { FoodManufacturer } from '../foodManufacturers/manufacturers.entity';
import { FoodRequest } from '../foodRequests/request.entity';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/foodManufacturers/manufacturers.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
OneToMany,
JoinColumn,
} from 'typeorm';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { Donation } from '../donations/donations.entity';
import { Allergen, DonateWastedFood, ManufacturerAttribute } from './types';
import { ApplicationStatus } from '../shared/types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FoodManufacturer } from './manufacturers.entity';
import { Repository } from 'typeorm';
import { validateId } from '../utils/validation.utils';
import { FoodManufacturerApplicationDto } from './dtos/manufacturer-application.dto';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { Role } from '../users/types';
import { ApplicationStatus } from '../shared/types';
import { userSchemaDto } from '../users/dtos/userSchema.dto';
Expand Down
3 changes: 2 additions & 1 deletion apps/backend/src/pantries/pantries.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
} from './types';
import { EmailsService } from '../emails/email.service';
import { ApplicationStatus } from '../shared/types';
import { User } from '../users/user.entity';
import { NotFoundException, UnauthorizedException } from '@nestjs/common';
import { User } from '../users/users.entity';
import { AuthenticatedRequest } from '../auth/authenticated-request';

const mockPantriesService = mock<PantriesService>();
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/pantries/pantries.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
JoinColumn,
ManyToMany,
} from 'typeorm';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import {
Activity,
AllergensConfidence,
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/pantries/pantries.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Pantry } from './pantries.entity';
import { AuthModule } from '../auth/auth.module';
import { OrdersModule } from '../orders/order.module';
import { EmailsModule } from '../emails/email.module';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { UsersModule } from '../users/users.module';

@Module({
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/pantries/pantries.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from './types';
import { ApplicationStatus } from '../shared/types';
import { UsersService } from '../users/users.service';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { Role } from '../users/types';

const mockRepository = mock<Repository<Pantry>>();
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/pantries/pantries.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { Pantry } from './pantries.entity';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { validateId } from '../utils/validation.utils';
import { ApplicationStatus } from '../shared/types';
import { PantryApplicationDto } from './dtos/pantry-application.dto';
Expand Down
13 changes: 12 additions & 1 deletion apps/backend/src/users/users.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { BadRequestException } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './user.entity';
import { User } from './users.entity';
import { Role } from './types';
import { userSchemaDto } from './dtos/userSchema.dto';

import { Test, TestingModule } from '@nestjs/testing';
import { mock } from 'jest-mock-extended';
import { AuthenticatedRequest } from '../auth/authenticated-request';

const mockUserService = mock<UsersService>();

Expand Down Expand Up @@ -46,6 +47,16 @@ describe('UsersController', () => {
expect(controller).toBeDefined();
});

describe('GET /my-id', () => {
it('should return the current user id', () => {
const req = { user: { id: 1 } } as AuthenticatedRequest;

const result = controller.getCurrentUserId(req);

expect(result).toBe(1);
});
});

describe('GET /:id', () => {
it('should return a user by id', async () => {
mockUserService.findOne.mockResolvedValue(mockUser1 as User);
Expand Down
12 changes: 11 additions & 1 deletion apps/backend/src/users/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,26 @@ import {
Post,
BadRequestException,
Body,
Req,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './user.entity';
import { User } from './users.entity';
import { Role } from './types';
import { userSchemaDto } from './dtos/userSchema.dto';
import { AuthenticatedRequest } from '../auth/authenticated-request';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { UseGuards } from '@nestjs/common';

@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}

@UseGuards(JwtAuthGuard)
@Get('/my-id')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we should set auth in some way here. @sam-schu should it be public and then we check if req.user.id is null or not and then throw an exception if it is? or should it be restricted to volunteers? or something else

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do Volunteers for now to match pantries

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't mark it as public because the user does have to be signed in, but we don't need to limit it to any specific role

getCurrentUserId(@Req() req: AuthenticatedRequest): number {
return req.user.id;
}

@Get('/:id')
async getUser(@Param('id', ParseIntPipe) userId: number): Promise<User> {
return this.usersService.findOne(userId);
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/users/users.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { forwardRef, Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './user.entity';
import { User } from './users.entity';
import { PantriesModule } from '../pantries/pantries.module';
import { AuthModule } from '../auth/auth.module';

Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/users/users.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Test } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UsersService } from './users.service';
import { User } from './user.entity';
import { User } from './users.entity';
import { Role } from './types';
import { mock } from 'jest-mock-extended';
import { In } from 'typeorm';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/users/users.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { User } from './user.entity';
import { User } from './users.entity';
import { Role } from './types';
import { validateId } from '../utils/validation.utils';
import { AuthService } from '../auth/auth.service';
Expand Down
3 changes: 3 additions & 0 deletions apps/backend/src/volunteers/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { User } from '../users/users.entity';

export type Assignments = Omit<User, 'pantries'> & { pantryIds: number[] };
2 changes: 1 addition & 1 deletion apps/backend/src/volunteers/volunteers.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BadRequestException, NotFoundException } from '@nestjs/common';
import { VolunteersController } from './volunteers.controller';
import { UsersController } from '../users/users.controller';
import { UsersService } from '../users/users.service';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { Role } from '../users/types';
import { Test, TestingModule } from '@nestjs/testing';
import { mock } from 'jest-mock-extended';
Expand Down
20 changes: 11 additions & 9 deletions apps/backend/src/volunteers/volunteers.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,35 @@ import {
Post,
Body,
} from '@nestjs/common';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { Pantry } from '../pantries/pantries.entity';
import { VolunteersService } from './volunteers.service';
import { Role } from '../users/types';
import { Roles } from '../auth/roles.decorator';
import { Assignments } from './types';

@Controller('volunteers')
export class VolunteersController {
constructor(private volunteersService: VolunteersService) {}

@Roles(Role.ADMIN)
@Get('/')
async getAllVolunteers(): Promise<
(Omit<User, 'pantries'> & { pantryIds: number[] })[]
> {
async getAllVolunteers(): Promise<Assignments[]> {
return this.volunteersService.getVolunteersAndPantryAssignments();
}

@Get('/:id')
async getVolunteer(@Param('id', ParseIntPipe) userId: number): Promise<User> {
return this.volunteersService.findOne(userId);
}

@Get('/:id/pantries')
async getVolunteerPantries(
@Param('id', ParseIntPipe) id: number,
): Promise<Pantry[]> {
return this.volunteersService.getVolunteerPantries(id);
}

@Get('/:id')
async getVolunteer(@Param('id', ParseIntPipe) userId: number): Promise<User> {
return this.volunteersService.findOne(userId);
}

@Post('/:id/pantries')
async assignPantries(
@Param('id', ParseIntPipe) id: number,
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/volunteers/volunteers.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { forwardRef, Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { PantriesModule } from '../pantries/pantries.module';
import { AuthModule } from '../auth/auth.module';
import { VolunteersController } from './volunteers.controller';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/volunteers/volunteers.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NotFoundException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { VolunteersService } from './volunteers.service';
import { Pantry } from '../pantries/pantries.entity';
import { testDataSource } from '../config/typeormTestDataSource';
Expand Down
13 changes: 6 additions & 7 deletions apps/backend/src/volunteers/volunteers.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from '../users/user.entity';
import { User } from '../users/users.entity';
import { Role } from '../users/types';
import { validateId } from '../utils/validation.utils';
import { Pantry } from '../pantries/pantries.entity';
import { PantriesService } from '../pantries/pantries.service';
import { UsersService } from '../users/users.service';
import { Assignments } from './types';

@Injectable()
export class VolunteersService {
Expand Down Expand Up @@ -34,9 +35,7 @@ export class VolunteersService {
return volunteer;
}

async getVolunteersAndPantryAssignments(): Promise<
(Omit<User, 'pantries'> & { pantryIds: number[] })[]
> {
async getVolunteersAndPantryAssignments(): Promise<Assignments[]> {
const volunteers = await this.usersService.findUsersByRoles([
Role.VOLUNTEER,
]);
Expand All @@ -45,15 +44,15 @@ export class VolunteersService {
const { pantries, ...volunteerWithoutPantries } = v;
return {
...volunteerWithoutPantries,
pantryIds: pantries!.map((p) => p.pantryId),
pantryIds: pantries?.map((p) => p.pantryId) || [],
};
});
}

async getVolunteerPantries(volunteerId: number): Promise<Pantry[]> {
validateId(volunteerId, 'Volunteer');
const volunteer = await this.findOne(volunteerId);
return volunteer.pantries!;
return volunteer.pantries || [];
}

async assignPantriesToVolunteer(
Expand All @@ -65,7 +64,7 @@ export class VolunteersService {
const volunteer = await this.findOne(volunteerId);

const pantries = await this.pantriesService.findByIds(pantryIds);
const existingPantries = volunteer.pantries!;
const existingPantries = volunteer.pantries || [];
const existingPantryIds = existingPantries.map((p) => p.pantryId);
const newPantries = pantries.filter(
(p) => !existingPantryIds.includes(p.pantryId),
Expand Down
15 changes: 12 additions & 3 deletions apps/frontend/src/api/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
OrderSummary,
UserDto,
OrderDetails,
FoodRequestSummaryDto,
Assignments,
} from 'types/types';

const defaultBaseUrl =
Expand Down Expand Up @@ -176,8 +176,12 @@ export class ApiClient {
.then((response) => response.data);
}

public async getVolunteers(): Promise<User[]> {
return this.get('/api/volunteers/') as Promise<User[]>;
public async getVolunteers(): Promise<Assignments[]> {
return this.get('/api/volunteers') as Promise<Assignments[]>;
}

public async getVolunteerPantries(userId: number): Promise<Pantry[]> {
return this.get(`/api/volunteers/${userId}/pantries`) as Promise<Pantry[]>;
}

public async updateUserVolunteerRole(
Expand Down Expand Up @@ -304,6 +308,11 @@ export class ApiClient {
const data = await this.get('/api/pantries/my-id');
return data as number;
}

public async getMyId(): Promise<number> {
const data = await this.get('/api/users/my-id');
return data as number;
}
}

export default new ApiClient();
Loading