refactor: use cookie instead of local storage for share token
This commit is contained in:
@@ -12,8 +12,6 @@ import {
|
||||
import { SkipThrottle } from "@nestjs/throttler";
|
||||
import * as contentDisposition from "content-disposition";
|
||||
import { Response } from "express";
|
||||
import { JwtGuard } from "src/auth/guard/jwt.guard";
|
||||
import { FileDownloadGuard } from "src/file/guard/fileDownload.guard";
|
||||
import { CreateShareGuard } from "src/share/guard/createShare.guard";
|
||||
import { ShareOwnerGuard } from "src/share/guard/shareOwner.guard";
|
||||
import { ShareSecurityGuard } from "src/share/guard/shareSecurity.guard";
|
||||
@@ -44,30 +42,8 @@ export class FileController {
|
||||
);
|
||||
}
|
||||
|
||||
@Get(":fileId/download")
|
||||
@UseGuards(ShareSecurityGuard)
|
||||
async getFileDownloadUrl(
|
||||
@Param("shareId") shareId: string,
|
||||
@Param("fileId") fileId: string
|
||||
) {
|
||||
const url = this.fileService.getFileDownloadUrl(shareId, fileId);
|
||||
|
||||
return { url };
|
||||
}
|
||||
|
||||
@Get("zip/download")
|
||||
@UseGuards(ShareSecurityGuard)
|
||||
async getZipArchiveDownloadURL(
|
||||
@Param("shareId") shareId: string,
|
||||
@Param("fileId") fileId: string
|
||||
) {
|
||||
const url = this.fileService.getFileDownloadUrl(shareId, fileId);
|
||||
|
||||
return { url };
|
||||
}
|
||||
|
||||
@Get("zip")
|
||||
@UseGuards(FileDownloadGuard)
|
||||
@UseGuards(ShareSecurityGuard)
|
||||
async getZip(
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Param("shareId") shareId: string
|
||||
@@ -82,7 +58,7 @@ export class FileController {
|
||||
}
|
||||
|
||||
@Get(":fileId")
|
||||
@UseGuards(FileDownloadGuard)
|
||||
@UseGuards(ShareSecurityGuard)
|
||||
async getFile(
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Param("shareId") shareId: string,
|
||||
|
||||
@@ -136,37 +136,5 @@ export class FileService {
|
||||
return fs.createReadStream(`./data/uploads/shares/${shareId}/archive.zip`);
|
||||
}
|
||||
|
||||
getFileDownloadUrl(shareId: string, fileId: string) {
|
||||
const downloadToken = this.generateFileDownloadToken(shareId, fileId);
|
||||
|
||||
return `${this.config.get(
|
||||
"APP_URL"
|
||||
)}/api/shares/${shareId}/files/${fileId}?token=${downloadToken}`;
|
||||
}
|
||||
|
||||
generateFileDownloadToken(shareId: string, fileId: string) {
|
||||
if (fileId == "zip") fileId = undefined;
|
||||
|
||||
return this.jwtService.sign(
|
||||
{
|
||||
shareId,
|
||||
fileId,
|
||||
},
|
||||
{
|
||||
expiresIn: "10min",
|
||||
secret: this.config.get("JWT_SECRET"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
verifyFileDownloadToken(shareId: string, token: string) {
|
||||
try {
|
||||
const claims = this.jwtService.verify(token, {
|
||||
secret: this.config.get("JWT_SECRET"),
|
||||
});
|
||||
return claims.shareId == shareId;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
|
||||
import { Request } from "express";
|
||||
import { FileService } from "src/file/file.service";
|
||||
|
||||
@Injectable()
|
||||
export class FileDownloadGuard implements CanActivate {
|
||||
constructor(private fileService: FileService) {}
|
||||
|
||||
async canActivate(context: ExecutionContext) {
|
||||
const request: Request = context.switchToHttp().getRequest();
|
||||
|
||||
const token = request.query.token as string;
|
||||
const { shareId } = request.params;
|
||||
|
||||
return this.fileService.verifyFileDownloadToken(shareId, token);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user