Skip to content

Commit

Permalink
Merge pull request #466 from boostcampwm2023/be-develop
Browse files Browse the repository at this point in the history
[merge] be-develop ๋ธŒ๋žœ์น˜๋ฅผ main์— ๋ฐ˜์˜ํ•จ
  • Loading branch information
yaongmeow authored Aug 31, 2024
2 parents 78157e8 + 4aca75c commit 345021f
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 16 deletions.
36 changes: 30 additions & 6 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,35 @@ jobs:
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USERNAME }}
password: ${{ secrets.SERVER_PASSWORD }}
key: ${{ secrets.SERVER_KEY }}
port: ${{ secrets.SERVER_PORT }}
script: |
docker login --username ${{ secrets.DOCKER_ID }} --password ${{ secrets.DOCKER_PASSWORD }}
docker pull traveline/traveline-docker
docker stop traveline-container || true
docker rm traveline-container || true
docker run -e DB_HOST=${{ secrets.DB_HOST }} -e DB_PORT=${{ secrets.DB_PORT }} -e DB_USER=${{ secrets.DB_USER }} -e DB_PASSWORD=${{ secrets.DB_PASSWORD }} -e DB_DATABASE=${{ secrets.DB_DATABASE }} -e NCP_ACCESS_KEY_ID=${{ secrets.NCP_ACCESS_KEY_ID }} -e NCP_SECRET_ACCESS_KEY=${{ secrets.NCP_SECRET_ACCESS_KEY }} -e NCP_REGION=${{ secrets.NCP_REGION }} -e JWT_SECRET_ACCESS=${{ secrets.JWT_SECRET_ACCESS }} -e JWT_SECRET_REFRESH=${{ secrets.JWT_SECRET_REFRESH }} -e CLIENT_ID=${{ secrets.CLIENT_ID }} -e TEAM_ID=${{ secrets.TEAM_ID }} -e KEY_ID=${{ secrets.KEY_ID }} -e AUTH_KEY_LINE1=${{ secrets.AUTH_KEY_LINE1 }} -e AUTH_KEY_LINE2=${{ secrets.AUTH_KEY_LINE2 }} -e AUTH_KEY_LINE3=${{ secrets.AUTH_KEY_LINE3 }} -e AUTH_KEY_LINE4=${{ secrets.AUTH_KEY_LINE4 }} -e KAKAO_REST_API_KEY=${{ secrets.KAKAO_REST_API_KEY }} -e AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} -e AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} -e AWS_REGION=${{ secrets.AWS_REGION }} -e GREENEYE_SECRET_KEY=${{ secrets.GREENEYE_SECRET_KEY }} -e GREENEYE_DOMAIN_ID=${{ secrets.GREENEYE_DOMAIN_ID }} -e GREENEYE_SIGNATURE=${{ secrets.GREENEYE_SIGNATURE }} -d -p ${{secrets.EXTERNAL_PORT}}:${{secrets.INTERNAL_PORT}} --name traveline-container traveline/traveline-docker
sudo docker login --username ${{ secrets.DOCKER_ID }} --password ${{ secrets.DOCKER_PASSWORD }}
sudo docker pull traveline/traveline-docker
sudo docker stop traveline-container || true
sudo docker rm traveline-container || true
sudo docker run -e DB_HOST=${{ secrets.DB_HOST }} \
-e DB_PORT=${{ secrets.DB_PORT }} \
-e DB_USER=${{ secrets.DB_USER }} \
-e DB_PASSWORD=${{ secrets.DB_PASSWORD }} \
-e DB_DATABASE=${{ secrets.DB_DATABASE }} \
-e NCP_ACCESS_KEY_ID=${{ secrets.NCP_ACCESS_KEY_ID }} \
-e NCP_SECRET_ACCESS_KEY=${{ secrets.NCP_SECRET_ACCESS_KEY }} \
-e NCP_REGION=${{ secrets.NCP_REGION }} \
-e JWT_SECRET_ACCESS=${{ secrets.JWT_SECRET_ACCESS }} \
-e JWT_SECRET_REFRESH=${{ secrets.JWT_SECRET_REFRESH }} \
-e CLIENT_ID=${{ secrets.CLIENT_ID }} \
-e TEAM_ID=${{ secrets.TEAM_ID }} \
-e KEY_ID=${{ secrets.KEY_ID }} \
-e AUTH_KEY_LINE1=${{ secrets.AUTH_KEY_LINE1 }} \
-e AUTH_KEY_LINE2=${{ secrets.AUTH_KEY_LINE2 }} \
-e AUTH_KEY_LINE3=${{ secrets.AUTH_KEY_LINE3 }} \
-e AUTH_KEY_LINE4=${{ secrets.AUTH_KEY_LINE4 }} \
-e KAKAO_REST_API_KEY=${{ secrets.KAKAO_REST_API_KEY }} \
-e AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} \
-e AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} \
-e AWS_REGION=${{ secrets.AWS_REGION }} \
-e GREENEYE_SECRET_KEY=${{ secrets.GREENEYE_SECRET_KEY }} \
-e GREENEYE_DOMAIN_ID=${{ secrets.GREENEYE_DOMAIN_ID }} \
-e GREENEYE_SIGNATURE=${{ secrets.GREENEYE_SIGNATURE }} \
-d -p ${{secrets.EXTERNAL_PORT}}:${{secrets.INTERNAL_PORT}} --name traveline-container traveline/traveline-docker
4 changes: 3 additions & 1 deletion BE/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
FROM node:18

ENV NODE_OPTIONS="--max-old-space-size=4096"

WORKDIR /app

COPY package.json package-lock.json ./
Expand All @@ -8,4 +10,4 @@ RUN npm ci

COPY . .

ENTRYPOINT ["npm", "run", "start"]
ENTRYPOINT ["npm", "run", "start"]
5 changes: 3 additions & 2 deletions BE/src/postings/postings.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ export class PostingsController {
description: '๊ฒ€์ƒ‰์–ด์™€ ์„ ํƒ ํƒœ๊ทธ์˜ ๊ต์ง‘ํ•ฉ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒŒ์‹œ๊ธ€์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.',
})
@ApiOkResponse({ schema: { example: search_OK } })
async search(@Query() searchPostingDto: SearchPostingDto) {
return this.postingsService.findAll(searchPostingDto);
async search(@Req() request, @Query() searchPostingDto: SearchPostingDto) {
const userId = request['user'].id;
return this.postingsService.findAll(userId, searchPostingDto);
}

@Get('titles')
Expand Down
11 changes: 10 additions & 1 deletion BE/src/postings/postings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import { Report } from './entities/report.entity';
import { Period, Season } from './postings.types';
import { BLOCKING_LIMIT } from './postings.constants';
import { StorageService } from 'src/storage/storage.service';
import { BlockRepository } from 'src/users/block.repository';

@Injectable()
export class PostingsService {
constructor(
private readonly userRepository: UserRepository,
private readonly blockRepository: BlockRepository,
private readonly postingsRepository: PostingsRepository,
private readonly likedsRepository: LikedsRepository,
private readonly reportsRepository: ReportsRepository,
Expand All @@ -44,8 +46,10 @@ export class PostingsService {
return this.postingsRepository.save(posting);
}

async findAll(dto: SearchPostingDto) {
async findAll(userId: string, dto: SearchPostingDto) {
const blockedIds = await this.findBlockedIds(userId);
const postings = await this.postingsRepository.findAll(
blockedIds,
dto.keyword,
dto.sorting,
dto.offset,
Expand Down Expand Up @@ -226,4 +230,9 @@ export class PostingsService {
reports: posting.reports,
};
}

private async findBlockedIds(blocker: string) {
const blocks = await this.blockRepository.findByBlocker(blocker);
return blocks.map((block) => block.blocked.id);
}
}
10 changes: 9 additions & 1 deletion BE/src/postings/repositories/postings.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class PostingsRepository {
}

async findAll(
blockedIds: string[],
keyword: string,
sorting: Sorting,
offset: number,
Expand All @@ -50,7 +51,14 @@ export class PostingsRepository {
withWhos: WithWho[]
) {
const conditions = ['p.title LIKE :keyword'];
let params: { [key: string]: string } = { keyword: `%${keyword}%` };
let params: { [key: string]: string | string[] } = {
keyword: `%${keyword}%`,
};

if (blockedIds.length > 0) {
conditions.push('p.writer NOT IN (:...blockedIds)');
params = { ...params, blockedIds };
}

if (budget) {
conditions.push('p.budget = :budget');
Expand Down
5 changes: 4 additions & 1 deletion BE/src/socialLogin/apple-login-strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ export class AppleLoginStrategy implements SocialLoginStrategy {

async login(
socialLoginRequestDto: SocialLoginRequestDto
): Promise<{ resourceId: string; email: string }> {
): Promise<{ resourceId: string; email?: string }> {
try {
const { idToken, email } = socialLoginRequestDto;
const resourceId = (await this.decodeIdToken(idToken)).sub;
if (!email) {
return { resourceId };
}
return { resourceId, email };
} catch (error) {
throw new UnauthorizedException('์œ ํšจํ•˜์ง€ ์•Š์€ ํ˜•์‹์˜ ํ† ํฐ์ž…๋‹ˆ๋‹ค.');
Expand Down
2 changes: 1 addition & 1 deletion BE/src/socialLogin/social-login-strategy.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SocialLoginRequestDto } from './dto/social-login-request.dto';
export interface SocialLoginStrategy {
login(
socialLoginRequestDto: SocialLoginRequestDto
): Promise<{ resourceId: string; email: string }>;
): Promise<{ resourceId: string; email?: string }>;
withdraw(
resourceId: string,
socialWithdrawRequestDto: SocialWithdrawRequestDto
Expand Down
38 changes: 38 additions & 0 deletions BE/src/users/block.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Inject, Injectable } from '@nestjs/common';
import { Block } from './entities/block.entity';
import { BLOCK_REPOSITORY } from './users.constants';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';

@Injectable()
export class BlockRepository {
constructor(
@Inject(BLOCK_REPOSITORY)
private blockRepository: Repository<Block>
) {}

save(blocker: User, blocked: User) {
return this.blockRepository.save({ blocker, blocked });
}

findByBlocker(blocker: string) {
return this.blockRepository
.createQueryBuilder('b')
.leftJoinAndSelect('b.blocker', 'x')
.leftJoinAndSelect('b.blocked', 'y')
.where('b.blocker = :blocker', { blocker })
.getMany();
}

findByBlockerAndBlocked(blocker: string, blocked: string) {
return this.blockRepository
.createQueryBuilder('b')
.leftJoinAndSelect('b.blocker', 'x')
.leftJoinAndSelect('b.blocked', 'y')
.where('b.blocker = :blocker AND b.blocked = :blocked', {
blocker,
blocked,
})
.getOne();
}
}
16 changes: 16 additions & 0 deletions BE/src/users/entities/block.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Entity, PrimaryGeneratedColumn, ManyToOne, JoinColumn } from 'typeorm';
import { User } from './user.entity';

@Entity()
export class Block {
@PrimaryGeneratedColumn('uuid')
id: string;

@ManyToOne(() => User, (user) => user.blockers, { nullable: false })
@JoinColumn({ name: 'blocker', referencedColumnName: 'id' })
blocker: User;

@ManyToOne(() => User, (user) => user.blockeds, { nullable: false })
@JoinColumn({ name: 'blocked', referencedColumnName: 'id' })
blocked: User;
}
7 changes: 7 additions & 0 deletions BE/src/users/entities/user.entity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Liked } from 'src/postings/entities/liked.entity';
import { Posting } from 'src/postings/entities/posting.entity';
import { Report } from 'src/postings/entities/report.entity';
import { Block } from './block.entity';
import {
Entity,
Column,
Expand Down Expand Up @@ -49,4 +50,10 @@ export class User {
@ManyToOne(() => SocialLogin, (socialLogin) => socialLogin.users)
@JoinColumn({ name: 'social_type', referencedColumnName: 'id' })
socials: SocialLogin;

@OneToMany(() => Block, (block) => block.blocker)
blockers: Block[];

@OneToMany(() => Block, (block) => block.blocked)
blockeds: Block[];
}
1 change: 1 addition & 0 deletions BE/src/users/users.constants.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const DATA_SOURCE = 'DATA_SOURCE';
export const USERS_REPOSITORY = 'USERS_REPOSITORY';
export const BLOCK_REPOSITORY = 'BLOCK_REPOSITORY';
13 changes: 13 additions & 0 deletions BE/src/users/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
UploadedFile,
UseGuards,
Req,
Post,
Param,
ParseUUIDPipe,
} from '@nestjs/common';
import { UsersService } from './users.service';
import {
Expand Down Expand Up @@ -110,4 +113,14 @@ export class UsersController {
checkDuplicatedName(@Query('name') name: string) {
return this.usersService.checkDuplicatedName(name);
}

@Post(':id/block')
@ApiOperation({
summary: 'ํŠน์ • ํšŒ์› ์ฐจ๋‹จ',
description: 'ํ˜„์žฌ ์œ ์ €๊ฐ€ id์— ํ•ด๋‹นํ•˜๋Š” ํšŒ์›์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.',
})
blockUser(@Req() request, @Param('id', ParseUUIDPipe) id: string) {
const userId = request['user'].id;
return this.usersService.blockUser(userId, id);
}
}
5 changes: 3 additions & 2 deletions BE/src/users/users.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import { usersProvider } from './users.providers';
import { UserRepository } from './users.repository';
import { StorageModule } from '../storage/storage.module';
import { DatabaseModule } from '../database/database.module';
import { BlockRepository } from './block.repository';

@Module({
imports: [DatabaseModule, StorageModule],
controllers: [UsersController],
providers: [UsersService, ...usersProvider, UserRepository],
exports: [UserRepository, UsersService],
providers: [UsersService, ...usersProvider, UserRepository, BlockRepository],
exports: [UserRepository, UsersService, BlockRepository],
})
export class UsersModule {}
12 changes: 11 additions & 1 deletion BE/src/users/users.providers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { Block } from './entities/block.entity';
import { User } from './entities/user.entity';
import { DataSource } from 'typeorm';
import { DATA_SOURCE, USERS_REPOSITORY } from './users.constants';
import {
BLOCK_REPOSITORY,
DATA_SOURCE,
USERS_REPOSITORY,
} from './users.constants';

export const usersProvider = [
{
provide: USERS_REPOSITORY,
useFactory: (dataSource: DataSource) => dataSource.getRepository(User),
inject: [DATA_SOURCE],
},
{
provide: BLOCK_REPOSITORY,
useFactory: (dataSource: DataSource) => dataSource.getRepository(Block),
inject: [DATA_SOURCE],
},
];
24 changes: 24 additions & 0 deletions BE/src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { UserRepository } from './users.repository';
import { CheckDuplicatedNameResponseDto } from './dto/check-duplicated-name-response.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { UpdateUserIpDto } from './dto/update-user-ip.dto';
import { BlockRepository } from './block.repository';

@Injectable()
export class UsersService {
constructor(
private userRepository: UserRepository,
private blockRepository: BlockRepository,
private readonly storageService: StorageService
) {}

Expand Down Expand Up @@ -113,4 +115,26 @@ export class UsersService {
async updateUserIp(id: string, updateUserIpDto: UpdateUserIpDto) {
return this.userRepository.update(id, updateUserIpDto);
}

async blockUser(blocker: string, blocked: string) {
if (blocker === blocked) {
throw new BadRequestException('์ž๊ธฐ ์ž์‹ ์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.');
}

const blockedUser = await this.userRepository.findById(blocked);
if (!blockedUser) {
throw new BadRequestException('์กด์žฌํ•˜์ง€ ์•Š๋Š” ํšŒ์›์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.');
}

const block = await this.blockRepository.findByBlockerAndBlocked(
blocker,
blocked
);
if (block) {
throw new BadRequestException('์ด๋ฏธ ์ฐจ๋‹จํ•œ ํšŒ์›์ž…๋‹ˆ๋‹ค.');
}

const blockerUser = await this.userRepository.findById(blocker);
return this.blockRepository.save(blockerUser, blockedUser);
}
}

0 comments on commit 345021f

Please sign in to comment.