Skip to content

Commit

Permalink
Merge pull request #8 from wang-bam-bbang/image
Browse files Browse the repository at this point in the history
Image
  • Loading branch information
Kimcheolhui authored Dec 1, 2024
2 parents 05fcfdd + 5745019 commit 5e921f6
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 19 deletions.
35 changes: 35 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.699.0",
"@aws-sdk/s3-request-presigner": "^3.701.0",
"@nestjs/axios": "^3.1.2",
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.3.0",
Expand Down
27 changes: 27 additions & 0 deletions src/image/image.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {
DeleteObjectCommand,
GetObjectCommand,
PutObjectCommand,
PutObjectTaggingCommand,
S3Client,
} from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import {
BadRequestException,
Injectable,
Expand Down Expand Up @@ -140,4 +142,29 @@ export class ImageService {
throw new InternalServerErrorException(error);
});
}

/**
* multiple keys에 대한 signed URLs 생성하기
* @param keys string[]
* @returns string[]
*/
async generateSignedUrls(keys: string[]): Promise<string[]> {
try {
const signedUrls = await Promise.all(
keys.map((key) =>
getSignedUrl(
this.s3Client,
new GetObjectCommand({ Bucket: this.bucketName, Key: key }),
{
expiresIn: 3600, // URL 유효 기간 (초), 1시간 설정
},
),
),
);
return signedUrls;
} catch (error) {
console.error('Error generating signed URLs:', error);
throw new InternalServerErrorException('Failed to generate signed URLs');
}
}
}
6 changes: 3 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ async function bootstrap() {
authorizationUrl: `${process.env.IDP_WEB_URL}/authorize?prompt=consent`,
tokenUrl: `${process.env.IDP_URL}/oauth/token`,
scopes: {
openid: '',
profile: '',
offline_access: '',
openid: 'openid',
profile: 'profile',
offline_access: 'offline_access',
},
},
},
Expand Down
66 changes: 50 additions & 16 deletions src/post/post.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ export class PostService {
async getPostList(postFilterDto: PostFilterDto): Promise<PostListDto> {
const postList = await this.postRepository.findPostList(postFilterDto);

const formattedPosts = postList.map((post) => ({
...post,
images: post.images.map((key) => `${this.s3Url}/${key}`),
}));
const formattedPosts = await Promise.all(
postList.map(async (post) => {
const signedUrls = await this.imageService.generateSignedUrls(
post.images,
);
return {
...post,
images: signedUrls, // Signed URL 반환
};
}),
);

const nextCursor =
postList.length > 0 ? postList[postList.length - 1].id : null;
Expand All @@ -46,15 +53,22 @@ export class PostService {
}

async getMyPostList(userUuid: string): Promise<PostListDto> {
const posts = await this.postRepository.findPostsByUser(userUuid);

const formattedPosts = posts.map((post) => ({
...post,
images: post.images.map((key) => `${this.s3Url}/${key}`),
}));
const postList = await this.postRepository.findPostsByUser(userUuid);

const formattedPosts = await Promise.all(
postList.map(async (post) => {
const signedUrls = await this.imageService.generateSignedUrls(
post.images,
);
return {
...post,
images: signedUrls, // Signed URL 반환
};
}),
);

return {
total: posts.length,
total: postList.length,
list: formattedPosts,
};
}
Expand All @@ -65,9 +79,11 @@ export class PostService {
if (!post) {
throw new NotFoundException('Post not found');
}
const signedUrls = await this.imageService.generateSignedUrls(post.images);

return {
...post,
images: post.images.map((key) => `${this.s3Url}/${key}`),
images: signedUrls,
};
}

Expand All @@ -84,7 +100,16 @@ export class PostService {
if (post.author.uuid != userUuid) {
throw new ForbiddenException("Don't have permission to update the post");
}
return this.postRepository.updatePost(id, updatePostDto);
const updatedPost = await this.postRepository.updatePost(id, updatePostDto);

const signedUrls = await this.imageService.generateSignedUrls(
updatedPost.images,
);

return {
...updatedPost,
images: signedUrls,
};
}

async deletePost(id: number, userUuid: string): Promise<void> {
Expand All @@ -107,11 +132,20 @@ export class PostService {
await this.imageService.validateImages(createPostDto.images);
}

// : Promise<Post & { author: Pick<User, 'name' | 'uuid'> }>
const newPost = this.postRepository.createPost(createPostDto, userUuid);
const newPost = await this.postRepository.createPost(
createPostDto,
userUuid,
);

const signedUrls = await this.imageService.generateSignedUrls(
newPost.images,
);

// TODO: FCM process need to be added.

return newPost;
return {
...newPost,
images: signedUrls,
};
}
}

0 comments on commit 5e921f6

Please sign in to comment.