Skip to content

Commit

Permalink
finished auth setup
Browse files Browse the repository at this point in the history
  • Loading branch information
hams7504 committed Apr 18, 2024
1 parent 04d4896 commit b11b3ce
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 0 deletions.
21 changes: 21 additions & 0 deletions apps/backend/src/users/dtos/update-user.request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { UserStatus, UserRole } from '../types';
import {
IsEmail,
IsOptional,
IsEnum,
} from 'class-validator';

export class UpdateUserRequestDTO {
@IsOptional()
@IsEnum(UserStatus)
status?: UserStatus;

@IsOptional()
@IsEmail()
email?: string;

@IsOptional()
@IsEnum(UserRole)
role?: UserRole;

}
10 changes: 10 additions & 0 deletions apps/backend/src/users/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export enum UserRole {
VOLUNTEER = 'Volunteer',
ADMIN = 'Admin',
}

export enum UserStatus {
PENDING = 'Approval Pending',
APPROVED = 'Approval Approved',
DENIED = 'Approval Denied'
}
51 changes: 51 additions & 0 deletions apps/backend/src/users/users.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {
IsEmail,
IsEnum,
IsPositive,
IsString,
IsPhoneNumber,
IsNumber,
IsDate,
} from 'class-validator';
import { Entity, Column } from 'typeorm';
import { UserRole, UserStatus } from './types';

@Entity()
export class User {
@Column({ primary: true, generated: true })
@IsPositive()
id: number;

@Column('varchar')
@IsEnum(UserStatus)
status: UserStatus;

@Column('varchar')
@IsEnum(UserRole)
role: UserRole;

@Column()
@IsString()
firstName: string;

@Column()
@IsString()
lastName: string;

@Column()
@IsEmail()
email: string;

@Column()
@IsPhoneNumber()
phoneNumber: number;

@Column()
@IsNumber()
zipCode: number;

@Column()
@IsDate()
birthDate: string;

}
128 changes: 128 additions & 0 deletions apps/backend/src/users/users.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {
Injectable,
UnauthorizedException,
NotFoundException,
BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { MongoRepository } from 'typeorm';
import { User } from './users.entity';
import { UpdateUserRequestDTO } from './dtos/update-user.request.dto';
import { UserStatus, UserRole } from './types';

@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: MongoRepository<User>,
) {}

async create(
email: string,
firstName: string,
lastName: string,
phoneNumber: number,
zipCode: number,
birthDate: string,
role: UserRole
): Promise<User> {
const user = this.usersRepository.create({
status: UserStatus.PENDING,
role: role,
firstName: firstName,
lastName: lastName,
email: email,
phoneNumber: phoneNumber,
zipCode: zipCode,
birthDate: birthDate
});

return this.usersRepository.save(user);
}

// TODO not currently used and not refactored
async findAll(currentUser: User, getAllMembers: boolean): Promise<User[]> {
if (!getAllMembers) return [];

if (currentUser.role === UserRole.VOLUNTEER) {
throw new UnauthorizedException();
}

const users: User[] = await this.usersRepository.find({
where: {
role: { $not: { $eq: UserRole.VOLUNTEER } },
},
});

return users;
}

// TODO refactor method to not take in currentUser
async findOne(currentUser: User, userId: number): Promise<User> {
const user = await this.usersRepository.findOne({
where: { id: userId }
});

if (!user) {
throw new NotFoundException(`User with ID ${userId} not found`);
}

const currentStatus = currentUser.role;
const targetStatus = user.role;

switch (currentStatus) {
case UserRole.ADMIN:
break;
case UserRole.VOLUNTEER:
if (targetStatus === UserRole.ADMIN) {
throw new NotFoundException(`User with ID ${userId} not found`);
}
if (
targetStatus === UserRole.VOLUNTEER &&
currentUser.id !== user.id
) {
throw new NotFoundException(`User with ID ${userId} not found`);
}
break;
}

return user;
}

findByEmail(email: string): Promise<User[]> {
return this.usersRepository.find({
where: { email },
relations: ['applications'],
});
}

async updateUser(
currentUser: User,
userId: number,
updateUserDTO: UpdateUserRequestDTO,
): Promise<User> {
const user: User = await this.findOne(currentUser, userId);

if (!user) {
throw new NotFoundException(`User with ID ${userId} not found`);
}

try {
await this.usersRepository.update({ id: userId }, updateUserDTO);
} catch (e) {
throw new BadRequestException('Cannot update user');
}

return await this.findOne(currentUser, userId);
}

async remove(currentUser: User, userId: number): Promise<User> {
const user = await this.findOne(currentUser, userId);

if (!user) {
throw new NotFoundException(`User with ID ${userId} not found`);
}

return this.usersRepository.remove(user);
}
}

0 comments on commit b11b3ce

Please sign in to comment.