Skip to content

Commit 5e921f6

Browse files
authored
Merge pull request #8 from wang-bam-bbang/image
Image
2 parents 05fcfdd + 5745019 commit 5e921f6

File tree

5 files changed

+116
-19
lines changed

5 files changed

+116
-19
lines changed

package-lock.json

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
},
2222
"dependencies": {
2323
"@aws-sdk/client-s3": "^3.699.0",
24+
"@aws-sdk/s3-request-presigner": "^3.701.0",
2425
"@nestjs/axios": "^3.1.2",
2526
"@nestjs/common": "^10.0.0",
2627
"@nestjs/config": "^3.3.0",

src/image/image.service.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import {
22
DeleteObjectCommand,
3+
GetObjectCommand,
34
PutObjectCommand,
45
PutObjectTaggingCommand,
56
S3Client,
67
} from '@aws-sdk/client-s3';
8+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
79
import {
810
BadRequestException,
911
Injectable,
@@ -140,4 +142,29 @@ export class ImageService {
140142
throw new InternalServerErrorException(error);
141143
});
142144
}
145+
146+
/**
147+
* multiple keys에 대한 signed URLs 생성하기
148+
* @param keys string[]
149+
* @returns string[]
150+
*/
151+
async generateSignedUrls(keys: string[]): Promise<string[]> {
152+
try {
153+
const signedUrls = await Promise.all(
154+
keys.map((key) =>
155+
getSignedUrl(
156+
this.s3Client,
157+
new GetObjectCommand({ Bucket: this.bucketName, Key: key }),
158+
{
159+
expiresIn: 3600, // URL 유효 기간 (초), 1시간 설정
160+
},
161+
),
162+
),
163+
);
164+
return signedUrls;
165+
} catch (error) {
166+
console.error('Error generating signed URLs:', error);
167+
throw new InternalServerErrorException('Failed to generate signed URLs');
168+
}
169+
}
143170
}

src/main.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ async function bootstrap() {
4040
authorizationUrl: `${process.env.IDP_WEB_URL}/authorize?prompt=consent`,
4141
tokenUrl: `${process.env.IDP_URL}/oauth/token`,
4242
scopes: {
43-
openid: '',
44-
profile: '',
45-
offline_access: '',
43+
openid: 'openid',
44+
profile: 'profile',
45+
offline_access: 'offline_access',
4646
},
4747
},
4848
},

src/post/post.service.ts

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,17 @@ export class PostService {
3030
async getPostList(postFilterDto: PostFilterDto): Promise<PostListDto> {
3131
const postList = await this.postRepository.findPostList(postFilterDto);
3232

33-
const formattedPosts = postList.map((post) => ({
34-
...post,
35-
images: post.images.map((key) => `${this.s3Url}/${key}`),
36-
}));
33+
const formattedPosts = await Promise.all(
34+
postList.map(async (post) => {
35+
const signedUrls = await this.imageService.generateSignedUrls(
36+
post.images,
37+
);
38+
return {
39+
...post,
40+
images: signedUrls, // Signed URL 반환
41+
};
42+
}),
43+
);
3744

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

4855
async getMyPostList(userUuid: string): Promise<PostListDto> {
49-
const posts = await this.postRepository.findPostsByUser(userUuid);
50-
51-
const formattedPosts = posts.map((post) => ({
52-
...post,
53-
images: post.images.map((key) => `${this.s3Url}/${key}`),
54-
}));
56+
const postList = await this.postRepository.findPostsByUser(userUuid);
57+
58+
const formattedPosts = await Promise.all(
59+
postList.map(async (post) => {
60+
const signedUrls = await this.imageService.generateSignedUrls(
61+
post.images,
62+
);
63+
return {
64+
...post,
65+
images: signedUrls, // Signed URL 반환
66+
};
67+
}),
68+
);
5569

5670
return {
57-
total: posts.length,
71+
total: postList.length,
5872
list: formattedPosts,
5973
};
6074
}
@@ -65,9 +79,11 @@ export class PostService {
6579
if (!post) {
6680
throw new NotFoundException('Post not found');
6781
}
82+
const signedUrls = await this.imageService.generateSignedUrls(post.images);
83+
6884
return {
6985
...post,
70-
images: post.images.map((key) => `${this.s3Url}/${key}`),
86+
images: signedUrls,
7187
};
7288
}
7389

@@ -84,7 +100,16 @@ export class PostService {
84100
if (post.author.uuid != userUuid) {
85101
throw new ForbiddenException("Don't have permission to update the post");
86102
}
87-
return this.postRepository.updatePost(id, updatePostDto);
103+
const updatedPost = await this.postRepository.updatePost(id, updatePostDto);
104+
105+
const signedUrls = await this.imageService.generateSignedUrls(
106+
updatedPost.images,
107+
);
108+
109+
return {
110+
...updatedPost,
111+
images: signedUrls,
112+
};
88113
}
89114

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

110-
// : Promise<Post & { author: Pick<User, 'name' | 'uuid'> }>
111-
const newPost = this.postRepository.createPost(createPostDto, userUuid);
135+
const newPost = await this.postRepository.createPost(
136+
createPostDto,
137+
userUuid,
138+
);
139+
140+
const signedUrls = await this.imageService.generateSignedUrls(
141+
newPost.images,
142+
);
112143

113144
// TODO: FCM process need to be added.
114145

115-
return newPost;
146+
return {
147+
...newPost,
148+
images: signedUrls,
149+
};
116150
}
117151
}

0 commit comments

Comments
 (0)