Skip to content
This repository was archived by the owner on Jun 29, 2025. It is now read-only.

Commit 2c47b2a

Browse files
committed
fix: add rule to check if user is owner of share
1 parent e818a29 commit 2c47b2a

File tree

6 files changed

+47
-17
lines changed

6 files changed

+47
-17
lines changed

backend/src/auth/auth.controller.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
Post,
77
} from "@nestjs/common";
88
import { ConfigService } from "@nestjs/config";
9-
import { UserDTO } from "src/user/dto/user.dto";
109

1110
import { AuthService } from "./auth.service";
1211
import { AuthRegisterDTO } from "./dto/authRegister.dto";

backend/src/file/file.controller.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,21 @@ import {
1010
UseGuards,
1111
UseInterceptors,
1212
} from "@nestjs/common";
13-
import { ConfigService } from "@nestjs/config";
1413
import { FileInterceptor } from "@nestjs/platform-express";
1514
import { Response } from "express";
1615
import { JwtGuard } from "src/auth/guard/jwt.guard";
1716
import { FileDownloadGuard } from "src/file/guard/fileDownload.guard";
1817
import { ShareDTO } from "src/share/dto/share.dto";
18+
import { ShareOwnerGuard } from "src/share/guard/shareOwner.guard";
1919
import { ShareSecurityGuard } from "src/share/guard/shareSecurity.guard";
2020
import { FileService } from "./file.service";
2121

2222
@Controller("shares/:shareId/files")
2323
export class FileController {
24-
constructor(
25-
private fileService: FileService,
26-
private config: ConfigService
27-
) {}
24+
constructor(private fileService: FileService) {}
25+
2826
@Post()
29-
@UseGuards(JwtGuard)
27+
@UseGuards(JwtGuard, ShareOwnerGuard)
3028
@UseInterceptors(
3129
FileInterceptor("file", {
3230
dest: "./uploads/_temp/",
@@ -43,7 +41,7 @@ export class FileController {
4341
file: Express.Multer.File,
4442
@Param("shareId") shareId: string
4543
) {
46-
return new ShareDTO().from( await this.fileService.create(file, shareId));
44+
return new ShareDTO().from(await this.fileService.create(file, shareId));
4745
}
4846

4947
@Get(":fileId/download")
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
2+
import { Reflector } from "@nestjs/core";
3+
import { User } from "@prisma/client";
4+
import { Request } from "express";
5+
import { ExtractJwt } from "passport-jwt";
6+
import { PrismaService } from "src/prisma/prisma.service";
7+
import { ShareService } from "src/share/share.service";
8+
9+
@Injectable()
10+
export class ShareOwnerGuard implements CanActivate {
11+
constructor(
12+
private prisma: PrismaService
13+
) {}
14+
15+
async canActivate(context: ExecutionContext) {
16+
const request: Request = context.switchToHttp().getRequest();
17+
const shareId = Object.prototype.hasOwnProperty.call(
18+
request.params,
19+
"shareId"
20+
)
21+
? request.params.shareId
22+
: request.params.id;
23+
24+
const share = await this.prisma.share.findUnique({
25+
where: { id: shareId },
26+
include: { security: true },
27+
});
28+
29+
30+
31+
return share.creatorId == (request.user as User).id;
32+
}
33+
}

backend/src/share/share.controller.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { MyShareDTO } from "./dto/myShare.dto";
1616
import { ShareDTO } from "./dto/share.dto";
1717
import { ShareMetaDataDTO } from "./dto/shareMetaData.dto";
1818
import { SharePasswordDto } from "./dto/sharePassword.dto";
19+
import { ShareOwnerGuard } from "./guard/shareOwner.guard";
1920
import { ShareSecurityGuard } from "./guard/shareSecurity.guard";
2021
import { ShareService } from "./share.service";
2122

@@ -50,14 +51,14 @@ export class ShareController {
5051
}
5152

5253
@Delete(":id")
53-
@UseGuards(JwtGuard)
54-
async remove(@Param("id") id: string, @GetUser() user: User) {
55-
await this.shareService.remove(id, user.id);
54+
@UseGuards(JwtGuard, ShareOwnerGuard)
55+
async remove(@Param("id") id: string) {
56+
await this.shareService.remove(id);
5657
}
5758

5859
@Post(":id/complete")
5960
@HttpCode(202)
60-
@UseGuards(JwtGuard)
61+
@UseGuards(JwtGuard, ShareOwnerGuard)
6162
async complete(@Param("id") id: string) {
6263
return new ShareDTO().from(await this.shareService.complete(id));
6364
}

backend/src/share/share.service.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,13 @@ export class ShareService {
132132
return share;
133133
}
134134

135-
async remove(shareId: string, userId: string) {
135+
async remove(shareId: string) {
136136
const share = await this.prisma.share.findUnique({
137137
where: { id: shareId },
138138
});
139139

140140
if (!share) throw new NotFoundException("Share not found");
141141

142-
if (share.creatorId != userId) throw new ForbiddenException();
143-
144142
await this.prisma.share.delete({ where: { id: shareId } });
145143
}
146144

frontend/src/pages/account/shares.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Group,
66
LoadingOverlay,
77
Space,
8+
Stack,
89
Table,
910
Text,
1011
Title,
@@ -39,14 +40,14 @@ const MyShares = () => {
3940
</Title>
4041
{shares.length == 0 ? (
4142
<Center style={{ height: "70vh" }}>
42-
<Group direction="column" align="center" spacing={10}>
43+
<Stack align="center" spacing={10}>
4344
<Title order={3}>It's empty here 👀</Title>
4445
<Text>You don't have any shares.</Text>
4546
<Space h={5} />
4647
<Button component={NextLink} href="/upload" variant="light">
4748
Create one
4849
</Button>
49-
</Group>
50+
</Stack>
5051
</Center>
5152
) : (
5253
<Table>

0 commit comments

Comments
 (0)