Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
andreacw5 committed Jul 11, 2024
2 parents dd4c939 + 6a0e0df commit 4180d1d
Show file tree
Hide file tree
Showing 11 changed files with 488 additions and 332 deletions.
42 changes: 21 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fileharbor",
"version": "1.1.0",
"version": "1.2.0",
"description": "FileHarbor is a file storage service that allows you to upload, download, and delete files",
"author": "Andrea Tombolato <andreacw96@gmail.com> (https://github.com/andreacw5)",
"private": true,
Expand All @@ -23,40 +23,40 @@
"dependencies": {
"@nestjs/axios": "^3.0.2",
"@nestjs/cache-manager": "^2.2.2",
"@nestjs/common": "^10.3.8",
"@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.3.8",
"@nestjs/common": "^10.3.10",
"@nestjs/config": "^3.2.3",
"@nestjs/core": "^10.3.10",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.3.8",
"@nestjs/swagger": "^7.3.1",
"@prisma/client": "^5.13.0",
"@nestjs/platform-express": "^10.3.10",
"@nestjs/swagger": "^7.4.0",
"@prisma/client": "^5.16.2",
"@types/multer": "^1.4.11",
"axios": "^1.6.8",
"axios": "^1.7.2",
"bcrypt": "^5.1.1",
"cache-manager": "^5.5.1",
"cache-manager": "^5.7.1",
"class-transformer": "^0.5.1",
"file-type-mime": "^0.3.10",
"file-type-mime": "^0.4.0",
"generate-password-ts": "^1.6.5",
"joi": "^17.13.0",
"joi": "^17.13.3",
"passport": "^0.7.0",
"passport-headerapikey": "^1.2.2",
"prisma": "^5.13.0",
"prisma": "^5.16.2",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"uuid": "^9.0.1"
"uuid": "^10.0.0"
},
"devDependencies": {
"@nestjs/cli": "^10.3.2",
"@nestjs/schematics": "^10.1.1",
"@nestjs/testing": "^10.3.3",
"@nestjs/cli": "^10.4.2",
"@nestjs/schematics": "^10.1.2",
"@nestjs/testing": "^10.3.10",
"@types/bcrypt": "^5.0.2",
"@types/cache-manager": "^4.0.6",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.12",
"@types/bcrypt": "^5.0.2",
"@types/multer": "^1.4.11",
"@types/node": "^20.11.26",
"@types/node": "^20.14.8",
"@types/supertest": "^6.0.2",
"@types/uuid": "^9.0.8",
"@types/uuid": "^10.0.0",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"eslint": "^8.57.0",
Expand All @@ -66,11 +66,11 @@
"prettier": "^3.2.5",
"source-map-support": "^0.5.21",
"supertest": "^6.3.4",
"ts-jest": "^29.1.2",
"ts-jest": "^29.2.2",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.4.5"
"typescript": "^5.5.3"
},
"jest": {
"moduleFileExtensions": [
Expand Down
10 changes: 10 additions & 0 deletions prisma/migrations/20240711151918_token_auth/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
Warnings:
- Added the required column `updatedAt` to the `localFiles` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "localFiles" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "token" TEXT,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;
3 changes: 3 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ model LocalFile {
optimized Boolean @default(false)
owner Owner? @relation(fields: [ownerId], references: [id])
ownerId String
token String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map(name: "localFiles")
}
Expand Down
1 change: 1 addition & 0 deletions src/modules/v1/localFiles/dto/create-local-file.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export class CreateLocalFileDto {
description?: string;
tags?: string[];
type?: string;
token?: string;
}
9 changes: 9 additions & 0 deletions src/modules/v1/localFiles/dto/get-file.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';

export class GetLocalFileDto {
@ApiProperty({
description: 'Security token for the file',
required: false,
})
token?: string;
}
24 changes: 24 additions & 0 deletions src/modules/v1/localFiles/dto/local-file.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Exclude } from 'class-transformer';
import { OwnerDto } from '../../owners/dto/owner.dto';

export class LocalFileDto {
id: string;
filename: string;
path: string;
mimetype: string;
size: number;
@Exclude()
ownerId: string;
description: string;
type: string;
tags: string[];
views: number;
downloads: number;
optimized: boolean;
createdAt: Date;
updatedAt: Date;
owner: OwnerDto;

@Exclude()
token: string;
}
23 changes: 23 additions & 0 deletions src/modules/v1/localFiles/localFiles.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
Delete,
Req,
UnauthorizedException,
HttpStatus,
Query,
} from '@nestjs/common';
import LocalFilesService from './localFiles.service';
import { Response } from 'express';
Expand All @@ -27,6 +29,7 @@ import {
ApiConsumes,
ApiHeaders,
ApiOperation,
ApiParam,
ApiPayloadTooLargeResponse,
ApiQuery,
ApiResponse,
Expand All @@ -40,6 +43,7 @@ import { ConfigService } from '@nestjs/config';
import { CreateLocalFileDto } from './dto/create-local-file.dto';
import { LocalFileFilterDto } from './dto/local-file-filter.dto';
import OwnersService from '../owners/owners.service';
import { GetLocalFileDto } from './dto/get-file.dto';

const GENERAL_UPLOADS_DIR: string = './uploads/';

Expand Down Expand Up @@ -121,13 +125,32 @@ export default class LocalFilesController {

@Get(':id')
@ApiOperation({ summary: 'Get a file by id' })
@ApiParam({
name: 'id',
description: 'Local file id',
})
@ApiQuery({
name: 'token',
required: false,
type: String,
description: 'Token for private files',
})
@UseInterceptors(CacheInterceptor)
async getFileById(
@Param('id') id: string,
@Query() query: GetLocalFileDto,
@Res({ passthrough: true }) response: Response,
) {
this.logger.debug(`Received request for file with id: ${id}`);
const file = await this.localFilesService.getFileById(id);
// If the file have a token, check if it matches the request token
if (file.token !== null && query.token !== file.token) {
this.logger.error(
`Token mismatch for file with id: ${id} and token: ${query.token}`,
);
return response.status(HttpStatus.UNAUTHORIZED).send('Token mismatch');
}

await this.localFilesService.updateViews(id);
const stream = createReadStream(join(process.cwd(), file.path));

Expand Down
19 changes: 16 additions & 3 deletions src/modules/v1/localFiles/localFiles.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../prisma.service';
import { LocalFile } from '@prisma/client';
import { HttpService } from '@nestjs/axios';
import { unlink } from 'fs';
import { LocalFileDto } from './dto/local-file.dto';
import { plainToInstance } from 'class-transformer';

@Injectable()
class LocalFilesService {
Expand Down Expand Up @@ -73,10 +74,22 @@ class LocalFilesService {
* Gets all files
* @param filters
*/
async getAllFiles(filters: object): Promise<LocalFile[]> {
return this.prisma.localFile.findMany({
async getAllFiles(filters: object): Promise<LocalFileDto[]> {
const files = await this.prisma.localFile.findMany({
where: filters,
include: {
owner: {
select: {
id: true,
name: true,
domain: true,
externalId: true,
},
},
},
});

return plainToInstance(LocalFileDto, files);
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/modules/v1/owners/dto/owner.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Exclude } from 'class-transformer';

export class OwnerDto {
id: string;
name: string;
@Exclude()
email: string;
externalId: string;
domain: string;
@Exclude()
password: string;
createdAt: Date;
updatedAt: Date;
}
2 changes: 1 addition & 1 deletion src/modules/v1/owners/owners.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class OwnersService {
const password = await this.authService.generateAPassword();
return this.prisma.owner.create({
data: {
name: data.name || '',
name: data.name || data.domain,
externalId: data.externalId,
domain: data.domain,
password: password,
Expand Down
Loading

0 comments on commit 4180d1d

Please sign in to comment.