Skip to content

Commit 7252a7f

Browse files
authored
Merge branch 'main' into patch/wechat
2 parents 74a2dc2 + 5134cf1 commit 7252a7f

15 files changed

+139
-72
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Module } from '@nestjs/common';
2-
import { ResourcesModule } from 'omnibox-backend/resources/resources.module';
32
import { PermissionsModule } from 'omnibox-backend/permissions/permissions.module';
43
import { AttachmentsController } from 'omnibox-backend/attachments/attachments.controller';
54
import { AttachmentsService } from 'omnibox-backend/attachments/attachments.service';
65
import { AuthModule } from 'omnibox-backend/auth/auth.module';
6+
import { MinioModule } from 'omnibox-backend/minio/minio.module';
77

88
@Module({
99
exports: [AttachmentsService],
1010
providers: [AttachmentsService],
1111
controllers: [AttachmentsController],
12-
imports: [PermissionsModule, ResourcesModule, AuthModule],
12+
imports: [PermissionsModule, MinioModule, AuthModule],
1313
})
1414
export class AttachmentsModule {}

src/attachments/attachments.service.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import {
77
NotFoundException,
88
} from '@nestjs/common';
99
import { Response } from 'express';
10-
import { MinioService } from 'omnibox-backend/resources/minio/minio.service';
10+
import { MinioService } from 'omnibox-backend/minio/minio.service';
1111
import { PermissionsService } from 'omnibox-backend/permissions/permissions.service';
1212
import { ResourcePermission } from 'omnibox-backend/permissions/resource-permission.enum';
13-
import { objectStreamResponse } from 'omnibox-backend/resources/utils';
13+
import { objectStreamResponse } from 'omnibox-backend/minio/utils';
1414

1515
@Injectable()
1616
export class AttachmentsService {
@@ -38,12 +38,16 @@ export class AttachmentsService {
3838
}
3939
}
4040

41+
minioPath(attachmentId: string): string {
42+
return `attachments/${attachmentId}`;
43+
}
44+
4145
async checkAttachment(
4246
namespaceId: string,
4347
resourceId: string,
4448
attachmentId: string,
4549
) {
46-
const info = await this.minioService.info(attachmentId);
50+
const info = await this.minioService.info(this.minioPath(attachmentId));
4751
if (
4852
info.metadata.namespaceId === namespaceId ||
4953
info.metadata.resourceId === resourceId
@@ -53,6 +57,27 @@ export class AttachmentsService {
5357
throw new NotFoundException(attachmentId);
5458
}
5559

60+
async uploadAttachment(
61+
namespaceId: string,
62+
resourceId: string,
63+
userId: string,
64+
filename: string,
65+
buffer: Buffer,
66+
mimetype: string,
67+
) {
68+
await this.checkPermission(
69+
namespaceId,
70+
resourceId,
71+
userId,
72+
ResourcePermission.CAN_EDIT,
73+
);
74+
const { id } = await this.minioService.put(filename, buffer, mimetype, {
75+
metadata: { namespaceId, resourceId, userId },
76+
folder: 'attachments',
77+
});
78+
return id;
79+
}
80+
5681
async uploadAttachments(
5782
namespaceId: string,
5883
resourceId: string,
@@ -72,13 +97,13 @@ export class AttachmentsService {
7297
try {
7398
const filename: string = encodeFileName(file.originalname);
7499
file.originalname = filename;
75-
const { id } = await this.minioService.put(
100+
const id = await this.uploadAttachment(
101+
namespaceId,
102+
resourceId,
103+
userId,
76104
filename,
77105
file.buffer,
78106
file.mimetype,
79-
{
80-
metadata: { namespaceId, resourceId, userId },
81-
},
82107
);
83108
uploaded.push({
84109
name: filename,
@@ -111,7 +136,9 @@ export class AttachmentsService {
111136
resourceId,
112137
attachmentId,
113138
);
114-
const stream = await this.minioService.getObject(attachmentId);
139+
const stream = await this.minioService.getObject(
140+
this.minioPath(attachmentId),
141+
);
115142
return objectStreamResponse({ stream, ...info }, httpResponse);
116143
}
117144

@@ -128,7 +155,7 @@ export class AttachmentsService {
128155
ResourcePermission.CAN_EDIT,
129156
);
130157
await this.checkAttachment(namespaceId, resourceId, attachmentId);
131-
await this.minioService.removeObject(attachmentId);
158+
await this.minioService.removeObject(this.minioPath(attachmentId));
132159
return { id: attachmentId, success: true };
133160
}
134161

@@ -137,7 +164,9 @@ export class AttachmentsService {
137164
userId: string,
138165
httpResponse: Response,
139166
) {
140-
const objectResponse = await this.minioService.get(attachmentId);
167+
const objectResponse = await this.minioService.get(
168+
this.minioPath(attachmentId),
169+
);
141170
const { namespaceId, resourceId } = objectResponse.metadata;
142171

143172
await this.checkPermission(

src/auth/auth.service.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { JwtService } from '@nestjs/jwt';
1+
import { JsonWebTokenError, JwtService, TokenExpiredError } from '@nestjs/jwt';
22
import { User } from 'omnibox-backend/user/entities/user.entity';
33
import { DataSource, EntityManager } from 'typeorm';
44
import { MailService } from 'omnibox-backend/mail/mail.service';
@@ -25,6 +25,7 @@ import { NamespaceRole } from 'omnibox-backend/namespaces/entities/namespace-mem
2525
@Injectable()
2626
export class AuthService {
2727
private readonly logger = new Logger(AuthService.name);
28+
private readonly knownErrors = [JsonWebTokenError, TokenExpiredError];
2829

2930
constructor(
3031
private readonly jwtService: JwtService,
@@ -280,7 +281,9 @@ export class AuthService {
280281
try {
281282
return this.jwtService.verify(token);
282283
} catch (error) {
283-
this.logger.error({ error });
284+
if (!this.knownErrors.some((cls) => error instanceof cls)) {
285+
this.logger.error({ error });
286+
}
284287
throw new UnauthorizedException('Invalid or expired token.');
285288
}
286289
}

src/minio/minio.module.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from '@nestjs/common';
2+
import { MinioService } from 'omnibox-backend/minio/minio.service';
3+
4+
@Module({
5+
exports: [MinioService],
6+
providers: [MinioService],
7+
controllers: [],
8+
imports: [],
9+
})
10+
export class MinioModule {}

src/resources/minio/minio.service.spec.ts renamed to src/minio/minio.service.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Test, TestingModule } from '@nestjs/testing';
22
import { ConfigModule } from '@nestjs/config';
3-
import { MinioService } from 'omnibox-backend/resources/minio/minio.service';
3+
import { MinioService } from 'omnibox-backend/minio/minio.service';
44

55
export const base64img: string =
66
'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAkCAYAAACe0YppAAAAAXNSR0IArs4c6QAAAGxlWElmTU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAACQAAAAAQAAAJAAAAABAAKgAgAEAAAAAQAAAB6gAwAEAAAAAQAAACQAAAAAS/p+JAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAzdJREFUWAmlWE1LMlEUPpotKgwDQUGoEIIgpEW0UBFBxITatGzfH+j/tGwZtO8LiihRgsCQaGeLIFoUpVJQ+fYM3cv9ODNzezube+85zz3Pc8Yzd2aMzMzMDMnRRkZGKJFIWOivry96enqy/EGOWFDQjG1sbND6+rrp9tabm5u/Io+yWXyc+XzeJ0K0urrqG+MCzsSjo6OUSqW4HJ4vSBS3yZm4Wq1SJBLhcng+iII4V3MmLpfLgTkhCuJczZk4m82G5gwTpyZwIl5aWiLcSqpdX1/Tx8eH6iIXcWKDE3GtVhN4OZ6dnVG325VrTCAOIl3MiXhhYUHLNRwO6fT0lC4uLjQ/FpxIC/TtCCWenp6msbExbS9Oqff3dzo6OtL8WJgiLcCPI5SYOxiurq687S8vL/T6+qrlhkiIDbNQYu43UyvtdDoWByfWBAUST05O0tTUlLYHnXxzcyN9x8fHci4mnFgRE2Mgcb1eFzg5mp18eXlJaDbVIBaigyyQuFgsWnvNTgbp/f29heNEqyBfYtyTmUxGxXpz9fcVwWazKaZy5ETL4PfElxjHn/lQQAejk007ODgwXZ5o87RTQb7ElUpFxXlzroMReHh4oLe3Nw0P0UFnty/x3NyclggLroMF6Pb2VkzlyIkXQZY4l8tRLKa/FaGJ0MF+hiPUNE68wLDEXEeic83bRiTBiIeGGYd4FMGZXtYPggOjw3d3d7kc0mc2IwIoot1uS4yYWMTpdJomJiZEXBu5xBqAWXBFAGZd6rW1NWb7/7tQBIoxzSJeXl42MX9ec8Vol3p8fJySyaRFtLe3R4+Pj5afc+BFYHZ2VguhmO3tbc2nEa+srGhBLD4/P2lnZ8fy+zn6/T5tbW1pYRSDogaDgfRrl7pUKsmAmNzd3Ymp03h+fm7dVthoFiWJo9Eo++bQaDScCAUIH3A4Qk0zi5LEhULBeihg8+HhoZkjdN1qtSwMXofU21ESc18BvV6Pnp+frSRhjv39fQsCUvVRKYnn5+ctsPqKYwUDHDhe8RZqmlqcRwxS7oPr5OTE3Ou85p5WanEe8eLiopUQB/5vG0tNwolGcfF43INFfvNXhJr4r/N/ctvrkhk6znEAAAAASUVORK5CYII=';

src/resources/minio/minio.service.ts renamed to src/minio/minio.service.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface PutOptions {
99
id?: string;
1010
metadata?: Record<string, any>;
1111
bucket?: string;
12+
folder?: string;
1213
}
1314

1415
export interface PutResponse extends UploadedObjectInfo {
@@ -57,7 +58,7 @@ export class MinioService {
5758
});
5859

5960
this.bucket =
60-
this.configService.get<string>('OBB_MINIO_BUCKET') || 'default';
61+
this.configService.get<string>('OBB_MINIO_BUCKET') || 'omnibox';
6162

6263
this.minioClient
6364
.bucketExists(this.bucket)
@@ -167,9 +168,10 @@ export class MinioService {
167168
metadata = {},
168169
bucket = this.bucket,
169170
} = options || {};
171+
const path: string = options?.folder ? `${options.folder}/${id}` : id;
170172
const info = await this.minioClient.putObject(
171173
bucket,
172-
id,
174+
path,
173175
buffer,
174176
buffer.length,
175177
{

src/resources/utils.ts renamed to src/minio/utils.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,5 @@
1+
import { GetResponse as ObjectResponse } from 'omnibox-backend/minio/minio.service';
12
import { Response } from 'express';
2-
import { ResourcesService } from 'omnibox-backend/resources/resources.service';
3-
import { GetResponse as ObjectResponse } from 'omnibox-backend/resources/minio/minio.service';
4-
5-
export async function fileResponse(
6-
resourceId: string,
7-
response: Response,
8-
resourcesService: ResourcesService,
9-
) {
10-
const { fileStream, resource } =
11-
await resourcesService.downloadFile(resourceId);
12-
const encodedName = encodeURIComponent(resource.name);
13-
response.setHeader(
14-
'Content-Disposition',
15-
`attachment; filename="${encodedName}"`,
16-
);
17-
response.setHeader(
18-
'Content-Type',
19-
resource.attrs?.mimetype || 'application/octet-stream',
20-
);
21-
fileStream.pipe(response);
22-
}
233

244
export function objectStreamResponse(
255
objectResponse: ObjectResponse,

src/resources/file-resources.controller.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Response } from 'express';
2-
import { fileResponse } from 'omnibox-backend/resources/utils';
32
import { FileInterceptor } from '@nestjs/platform-express';
43
import { ResourcesService } from 'omnibox-backend/resources/resources.service';
54
import {
@@ -116,11 +115,11 @@ export class FileResourcesController {
116115
);
117116
}
118117

119-
@Get('files/:resourceId')
118+
@Get(':resourceId')
120119
async downloadFile(
121120
@Param('resourceId') resourceId: string,
122121
@Res() res: Response,
123122
) {
124-
return await fileResponse(resourceId, res, this.resourcesService);
123+
return await this.resourcesService.fileResponse(resourceId, res);
125124
}
126125
}

src/resources/internal.resource.controller.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Response } from 'express';
2-
import { fileResponse } from 'omnibox-backend/resources/utils';
32
import { Controller, Get, Param, Res } from '@nestjs/common';
43
import { ResourcesService } from 'omnibox-backend/resources/resources.service';
54
import { Public } from 'omnibox-backend/auth/decorators/public.decorator';
@@ -11,6 +10,6 @@ export class InternalResourcesController {
1110
@Public()
1211
@Get('files/:id')
1312
async downloadFile(@Param('id') resourceId: string, @Res() res: Response) {
14-
return await fileResponse(resourceId, res, this.resourcesService);
13+
return await this.resourcesService.fileResponse(resourceId, res);
1514
}
1615
}

src/resources/resources.module.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import { Resource } from 'omnibox-backend/resources/resources.entity';
44
import { ResourcesService } from 'omnibox-backend/resources/resources.service';
55
import { ResourcesController } from 'omnibox-backend/resources/resources.controller';
66
import { Task } from 'omnibox-backend/tasks/tasks.entity';
7-
import { MinioService } from 'omnibox-backend/resources/minio/minio.service';
87
import { InternalResourcesController } from 'omnibox-backend/resources/internal.resource.controller';
98
import { PermissionsModule } from 'omnibox-backend/permissions/permissions.module';
109
import { FileResourcesController } from 'omnibox-backend/resources/file-resources.controller';
10+
import { MinioModule } from 'omnibox-backend/minio/minio.module';
1111

1212
@Module({
13-
exports: [ResourcesService, MinioService],
14-
providers: [ResourcesService, MinioService],
13+
exports: [ResourcesService],
14+
providers: [ResourcesService],
1515
controllers: [
1616
ResourcesController,
1717
InternalResourcesController,
@@ -21,6 +21,7 @@ import { FileResourcesController } from 'omnibox-backend/resources/file-resource
2121
TypeOrmModule.forFeature([Resource]),
2222
TypeOrmModule.forFeature([Task]),
2323
PermissionsModule,
24+
MinioModule,
2425
],
2526
})
2627
export class ResourcesModule {}

0 commit comments

Comments
 (0)