Skip to content

Commit

Permalink
Dev init backend (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
automerge-pingpong[bot] committed Oct 24, 2023
2 parents 5a02d8b + 1987e80 commit dc07a01
Show file tree
Hide file tree
Showing 19 changed files with 11,766 additions and 11,361 deletions.
22,881 changes: 11,570 additions & 11,311 deletions backend/code/package-lock.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions backend/code/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "hands_ondirt",
"name": "PongGame",
"volta": {
"node": "18.18.0",
"npm": "10.1.0"
Expand All @@ -16,7 +16,7 @@
"start:dev": "npm run db:generate && nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"db:generate": "prisma generate",
"db:generate": "prisma generate",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
Expand All @@ -35,8 +35,10 @@
"@nestjs/platform-express": "^10.0.0",
"@nestjs/platform-socket.io": "^10.2.6",
"@nestjs/swagger": "^7.1.12",
"@nestjs/throttler": "^5.0.0",
"@nestjs/websockets": "^10.2.6",
"@prisma/client": "^5.2.0",
"@types/qrcode": "^1.5.4",
"bcrypt": "^5.1.1",
"bull": "^4.11.3",
"class-transformer": "^0.5.1",
Expand All @@ -45,10 +47,12 @@
"cookie-parser": "^1.4.6",
"dotenv": "^16.3.1",
"express-session": "^1.17.3",
"otplib": "^12.0.1",
"passport": "^0.6.0",
"passport-42": "^1.2.6",
"passport-jwt": "^4.0.1",
"prisma": "^5.2.0",
"qrcode": "^1.5.3",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"socket.io": "^4.7.2",
Expand Down
2 changes: 2 additions & 0 deletions backend/code/prisma/dbml/schema.dbml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Table users {
discreption String [not null, default: '']
avatar String
tfaEnabled Boolean [not null, default: false]
tfaSecret String
tfaStatus Boolean [not null, default: false]
left_friends friends [not null]
right_friends friends [not null]
matches matches [not null]
Expand Down
2 changes: 2 additions & 0 deletions backend/code/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ model User {
discreption String @default("")
avatar String?
tfaEnabled Boolean @default(false)
tfaSecret String?
tfaStatus Boolean @default(false)
left_friends Friend[] @relation("from")
right_friends Friend[] @relation("to")
matches Match[] @relation("participant1")
Expand Down
14 changes: 12 additions & 2 deletions backend/code/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma/prisma.service';
import { PrismaModule } from './prisma/prisma.module';
import { AuthModule } from './auth/auth.module';
import { AppController } from './app.controller';
Expand All @@ -13,6 +12,8 @@ import { EventEmitterModule } from '@nestjs/event-emitter';
import { Gateways } from './gateways/gateways.gateway';
import { GameModule } from './game/game.module';
import { LeaderBoardModule } from './leaderboard/leaderboard.module';
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';

@Module({
imports: [
Expand All @@ -27,8 +28,17 @@ import { LeaderBoardModule } from './leaderboard/leaderboard.module';
EventEmitterModule.forRoot(),
GameModule,
LeaderBoardModule,
ThrottlerModule.forRoot([
{
ttl: 6000,
limit: 1000000,
},
]),
],
controllers: [AppController],
providers: [PrismaService, Gateways],
providers: [Gateways, {
provide: APP_GUARD,
useClass: ThrottlerGuard,
}],
})
export class AppModule {}
2 changes: 2 additions & 0 deletions backend/code/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import { JwtUtilsModule } from './utils/jwt_utils/jwt_utils.module';
import { UsersService } from 'src/users/users.service';
import { JwtConsts } from './constants/constants';
import { CloudinaryService } from 'src/cloudinary/cloudinary.service';
import { UsersModule } from 'src/users/users.module';

@Module({
imports: [
JwtModule.register({ secret: JwtConsts.at_secret }),
JwtUtilsModule,
UsersModule,
],
providers: [
AuthService,
Expand Down
6 changes: 6 additions & 0 deletions backend/code/src/auth/guards/at.guard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
ExecutionContext,
HttpException,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
Expand All @@ -15,6 +16,11 @@ export class AtGuard extends AuthGuard('jwt') {
if (err || !user) {
throw err || new UnauthorizedException();
}
if (user.tfaEnabled) {
if (!user.tfaStatus) throw new HttpException('la7g inak', 403);
}
if (!user.profileFinished)
throw new HttpException('Please complete your profile', 403);
return user;
}
}
10 changes: 0 additions & 10 deletions backend/code/src/auth/guards/authenticated.guard.ts

This file was deleted.

8 changes: 5 additions & 3 deletions backend/code/src/auth/stratgies/at.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { JwtConsts } from '../constants/constants';
import { Request } from 'express';
import { Req } from '@nestjs/common';
import { Inject, Req } from '@nestjs/common';
import { JwtPayload } from '../types';
import { UsersService } from 'src/users/users.service';

export class AtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor() {
constructor(@Inject(UsersService) private userService: UsersService) {
super({
jwtFromRequest: ExtractJwt.fromExtractors([
AtStrategy.cookieExtractor,
Expand All @@ -24,6 +25,7 @@ export class AtStrategy extends PassportStrategy(Strategy, 'jwt') {
}

async validate(payload: any): Promise<JwtPayload> {
return { userId: payload.sub, username: payload.username };
const curruser = await this.userService.getUserById(payload.sub);
return { ...curruser, username: payload.username };
}
}
1 change: 1 addition & 0 deletions backend/code/src/auth/stratgies/ft.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class FtStrategy extends PassportStrategy(Strategy, '42') {

await this.usersService.updateUser(new_user.userId, {
avatar: `v${result.version}/${result.public_id}.${result.format}`,
tfaStatus: false,
});

const tokens = await this.jwtUtils.generateTokens(
Expand Down
2 changes: 1 addition & 1 deletion backend/code/src/messages/messages.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export class MessagesService {
}

const roomMember = room.members[0];
console.log(roomMember);

if (!roomMember) {
throw new HttpException(
Expand Down Expand Up @@ -82,6 +81,7 @@ export class MessagesService {
authorId: userId,
},
});

const responseMessage: MessageFormatDto = new MessageFormatDto(messageData);
this.eventEmitter.emit('sendMessages', responseMessage);
return responseMessage;
Expand Down
7 changes: 6 additions & 1 deletion backend/code/src/profile/dto/profile.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type PICTURE = {
};

export class ProfileDto {
constructor(userData: ProfileDtoProps) {
constructor(userData: ProfileDtoProps, is_friend: boolean) {
this.id = userData.userId;
this.profileFinished = userData.profileFinished;
this.tfa = userData.tfaEnabled;
Expand All @@ -38,6 +38,9 @@ export class ProfileDto {
large: `https://res.cloudinary.com/trandandan/image/upload/c_thumb,h_128,w_128/${userData.avatar}`,
};
this.username = userData.Username;
if (is_friend) {
this.friendship = [...userData.left_friends, ...userData.right_friends];
}
}

@ApiProperty({ example: 'cln8xxhut0000stofeef' })
Expand Down Expand Up @@ -68,4 +71,6 @@ export class ProfileDto {

@ApiProperty({ example: 'dexter' })
username: string;

friendship: Friend[];
}
19 changes: 15 additions & 4 deletions backend/code/src/profile/profile.controller.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import {
Body,
Controller,
FileTypeValidator,
Get,
HttpCode,
HttpStatus,
MaxFileSizeValidator,
Param,
ParseFilePipe,
Post,
UploadedFile,
UseGuards,
Expand All @@ -25,6 +28,7 @@ import {
ApiParam,
ApiTags,
} from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';

@ApiTags('profile')
@ApiCookieAuth('X-Acces-Token')
Expand All @@ -36,14 +40,13 @@ export class ProfileController {
@ApiOkResponse({ type: ProfileDto })
@UseGuards(AtGuard)
async getMe(@GetCurrentUser('userId') userId: string): Promise<ProfileDto> {
console.log(userId);
return await this.profileService.getProfile(userId);
}

@Post('me')
@ApiOkResponse({ type: ProfileDto })
@HttpCode(HttpStatus.OK)
@UseGuards(AtGuard)
@UseGuards(AuthGuard('jwt'))
updateMe(
@GetCurrentUser('userId') userId: string,
@Body() update_data: UpdateProfileDto,
Expand All @@ -64,7 +67,7 @@ export class ProfileController {
@Param('id') Id: string,
@GetCurrentUser('userId') userId: string,
) {
return this.profileService.getProfile(userId, Id);
return this.profileService.getFriendProfile(userId, Id);
}

@Post('avatar')
Expand All @@ -84,7 +87,15 @@ export class ProfileController {
@UseGuards(AtGuard)
uploadAvatar(
@GetCurrentUser('userId') userId: string,
@UploadedFile() file: Express.Multer.File,
@UploadedFile(
new ParseFilePipe({
validators: [
new MaxFileSizeValidator({ maxSize: 5e6 }),
new FileTypeValidator({ fileType: '.(png|jpeg|jpg)' }),
],
}),
)
file: Express.Multer.File,
) {
return this.profileService.uploadAvatar(userId, file);
}
Expand Down
30 changes: 17 additions & 13 deletions backend/code/src/profile/profile.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,28 @@ import { Readable } from 'stream';
export class ProfileService {
constructor(private usersService: UsersService) {}

async getProfile(
async getProfile(userId: string): Promise<ProfileDto> {
const user = await this.usersService.getUserById(userId);
if (!user) {
throw new HttpException('User not found', HttpStatus.NOT_FOUND);
}
return new ProfileDto(user, false);
}

async getFriendProfile(
userId: string,
friendId?: null | string,
friendId: string,
): Promise<ProfileDto> {
let id = userId;
if (friendId && friendId !== userId) {
const blockid = [userId, friendId].sort().join('-');
const block = await this.usersService.getBlockbyId(blockid);
if (block) {
throw new HttpException('User not found', HttpStatus.NOT_FOUND);
}
id = friendId;
const blockid = [userId, friendId].sort().join('-');
const block = await this.usersService.getBlockbyId(blockid);
if (block) {
throw new HttpException('User not found', HttpStatus.NOT_FOUND);
}
const user = await this.usersService.getUserById(id);
const user = await this.usersService.getUserById(friendId, userId);
if (!user) {
throw new HttpException('User not found', HttpStatus.NOT_FOUND);
}
return new ProfileDto(user);
return new ProfileDto(user, true);
}

async updateProfile(
Expand All @@ -49,7 +53,7 @@ export class ProfileService {
profileFinished: true,
});
}
return new ProfileDto(user);
return new ProfileDto(user, false);
}

async uploadAvatar(userId: string, file: Express.Multer.File) {
Expand Down
5 changes: 5 additions & 0 deletions backend/code/src/rooms/rooms.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ export class RoomsService {
select: { type: true, password: true },
});
if (!room) throw new HttpException('room not found', HttpStatus.NOT_FOUND);
if (room.type === 'protected' && !('password' in roomData))
throw new HttpException(
'missing password for protected room',
HttpStatus.BAD_REQUEST,
);
if (room.type == 'protected') {
const isPasswordCorrect = await bcrypt.compare(
roomData.password,
Expand Down
6 changes: 6 additions & 0 deletions backend/code/src/users/dto/two-factor.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { IsBoolean } from 'class-validator';

export class TwoFactorDto {
@IsBoolean()
activate: boolean;
}
2 changes: 2 additions & 0 deletions backend/code/src/users/dto/update-user.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,6 @@ export class UpdateUserDto {
avatar?: string;

discreption?: string;

tfaStatus?: boolean;
}
30 changes: 30 additions & 0 deletions backend/code/src/users/users.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import {
Body,
Controller,
Get,
HttpCode,
HttpStatus,
Post,
Query,
UseGuards,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { AtGuard } from 'src/auth/guards/at.guard';
import { usersSearchDto } from './dto/search-user.dto';
import { TwoFactorDto } from './dto/two-factor.dto';
import { GetCurrentUser } from 'src/auth/decorator/get_current_user.decorator';
import { AuthGuard } from '@nestjs/passport';

@Controller('users')
export class UsersController {
Expand All @@ -20,4 +25,29 @@ export class UsersController {
async getUsers(@Query() query: usersSearchDto) {
return this.usersService.getUsers(query.q);
}

@Post('twoFactorAuth')
@HttpCode(HttpStatus.OK)
@UseGuards(AtGuard)
async twoFactorAuth(
@Body() dataDto: TwoFactorDto,
@GetCurrentUser('userId') userId: string,
) {
return this.usersService.twoFactorAuth(userId, dataDto.activate);
}

@Get('2faQrCode')
@UseGuards(AtGuard)
async get2faQrCode(@GetCurrentUser('userId') userId: string) {
return this.usersService.genertQrcode(userId);
}

@Post('validate2fa')
@UseGuards(AuthGuard('jwt'))
async validate2fa(
@Body('otp') token: string,
@GetCurrentUser('userId') userId: string,
) {
return this.usersService.validateTwoFactorAuth(userId, token);
}
}
Loading

0 comments on commit dc07a01

Please sign in to comment.