Compare commits
2 Commits
ef8ba655f3
...
30026df2d0
Author | SHA1 | Date | |
---|---|---|---|
30026df2d0 | |||
d909f67a4c |
@ -3,9 +3,10 @@ import { DbModule } from "../db/db.module";
|
|||||||
import { StorageModule } from "../storage/storage.module";
|
import { StorageModule } from "../storage/storage.module";
|
||||||
import { FilesController } from "./files.controller";
|
import { FilesController } from "./files.controller";
|
||||||
import { FilesService } from "./files.service";
|
import { FilesService } from "./files.service";
|
||||||
|
import { CredentialsModule } from '../credentials/credentials.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [StorageModule, DbModule],
|
imports: [StorageModule, DbModule, CredentialsModule],
|
||||||
controllers: [FilesController],
|
controllers: [FilesController],
|
||||||
providers: [FilesService],
|
providers: [FilesService],
|
||||||
})
|
})
|
||||||
|
@ -62,7 +62,7 @@ export class FilesService {
|
|||||||
);
|
);
|
||||||
const fileNameWithoutSpaces = file.fileName.replace(/\s/g, "_");
|
const fileNameWithoutSpaces = file.fileName.replace(/\s/g, "_");
|
||||||
return new StreamableFile(fileBuffer, {
|
return new StreamableFile(fileBuffer, {
|
||||||
disposition: `attachment; filename="${fileNameWithoutSpaces}.${fileInformation.fileType.ext.toLowerCase()}"`,
|
disposition: `attachment; filename="${fileNameWithoutSpaces}.${fileInformation.fileType[0].extension.toLowerCase()}"`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ export class FilesService {
|
|||||||
.values({
|
.values({
|
||||||
fileName: data.get("fileName") as string,
|
fileName: data.get("fileName") as string,
|
||||||
checksum: saveResult.fileChecksum,
|
checksum: saveResult.fileChecksum,
|
||||||
extension: saveResult.fileType.ext,
|
extension: saveResult.fileType[0].extension,
|
||||||
fileSize: saveResult.fileSize,
|
fileSize: saveResult.fileSize,
|
||||||
fileType: saveResult.fileType.mime,
|
fileType: saveResult.fileType.mime,
|
||||||
isRestricted: Boolean(data.get("isRestricted")),
|
isRestricted: Boolean(data.get("isRestricted")),
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { MachinesController } from "apps/backend/src/app/machines/machines.controller";
|
import { MachinesController } from "apps/backend/src/app/machines/machines.controller";
|
||||||
import { MachinesService } from "apps/backend/src/app/machines/machines.service";
|
import { MachinesService } from "apps/backend/src/app/machines/machines.service";
|
||||||
|
import { DbModule } from 'apps/backend/src/app/db/db.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [DbModule],
|
||||||
controllers: [MachinesController],
|
controllers: [MachinesController],
|
||||||
providers: [MachinesService],
|
providers: [MachinesService],
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { DbModule } from "apps/backend/src/app/db/db.module";
|
import { DbModule } from "../db/db.module";
|
||||||
import { StorageService } from "apps/backend/src/app/storage/storage.service";
|
import { StorageService } from "../storage/storage.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [DbModule],
|
imports: [DbModule],
|
||||||
providers: [StorageService],
|
providers: [StorageService],
|
||||||
|
exports: [StorageService]
|
||||||
})
|
})
|
||||||
export class StorageModule {}
|
export class StorageModule {}
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
} from "apps/backend/src/app/db/schema";
|
} from "apps/backend/src/app/db/schema";
|
||||||
import { IFileInformation } from "apps/backend/src/app/storage/storage.types";
|
import { IFileInformation } from "apps/backend/src/app/storage/storage.types";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import FileType from "file-type";
|
import { filetypeinfo } from 'magic-bytes.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StorageService {
|
export class StorageService {
|
||||||
@ -61,7 +61,7 @@ export class StorageService {
|
|||||||
return allowedMime.has(currentMime);
|
return allowedMime.has(currentMime);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileType = await FileType.fileTypeFromBuffer(file);
|
const fileType = filetypeinfo(file);
|
||||||
|
|
||||||
// Array of MIMEs with possible duplicate field
|
// Array of MIMEs with possible duplicate field
|
||||||
const _mimes: Array<string> = [];
|
const _mimes: Array<string> = [];
|
||||||
@ -106,7 +106,7 @@ export class StorageService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkMime(mimeSet, fileType.mime))
|
if (!checkMime(mimeSet, fileType[0].mime))
|
||||||
throw new BadRequestException({
|
throw new BadRequestException({
|
||||||
cause: "MIME type",
|
cause: "MIME type",
|
||||||
description: `Invalid MIME type. Allowed MIME types are: ${[...mimeSet].join(", ")}.`,
|
description: `Invalid MIME type. Allowed MIME types are: ${[...mimeSet].join(", ")}.`,
|
||||||
@ -164,15 +164,15 @@ export class StorageService {
|
|||||||
fileDisplayName: string,
|
fileDisplayName: string,
|
||||||
isDocumentation?: boolean,
|
isDocumentation?: boolean,
|
||||||
): Promise<IFileInformation> {
|
): Promise<IFileInformation> {
|
||||||
const fileType = await FileType.fileTypeFromBuffer(file);
|
const fileType = filetypeinfo(file);
|
||||||
const checksum = await this.getChecksum(file);
|
const checksum = await this.getChecksum(file);
|
||||||
const fileName = `${isDocumentation ? "doc" : "file"}-${checksum}.${fileType.ext.toLowerCase()}`;
|
const fileName = `${isDocumentation ? "doc" : "file"}-${checksum}.${fileType[0].extension.toLowerCase()}`;
|
||||||
return {
|
return {
|
||||||
fileName: fileName,
|
fileName: fileName,
|
||||||
fileDisplayName: fileDisplayName,
|
fileDisplayName: fileDisplayName,
|
||||||
fileSize: file.byteLength,
|
fileSize: file.byteLength,
|
||||||
fileChecksum: checksum,
|
fileChecksum: checksum,
|
||||||
fileType: fileType,
|
fileType: fileType[0],
|
||||||
isDocumentation: isDocumentation || false,
|
isDocumentation: isDocumentation || false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { StreamableFile } from "@nestjs/common";
|
import { StreamableFile } from "@nestjs/common";
|
||||||
import FileType from "file-type";
|
import { GuessedFile } from 'magic-bytes.js/dist/model/tree';
|
||||||
|
|
||||||
export interface IFileInformation {
|
export interface IFileInformation {
|
||||||
fileDisplayName: string;
|
fileDisplayName: string;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
fileChecksum: string;
|
fileChecksum: string;
|
||||||
isDocumentation: boolean;
|
isDocumentation: boolean;
|
||||||
fileType: FileType.FileTypeResult;
|
fileType: GuessedFile;
|
||||||
fileSize: number;
|
fileSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
64
package.json
64
package.json
@ -3,7 +3,10 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"check": "biome check --skip-errors --apply apps"
|
"check": "biome check --skip-errors --apply apps",
|
||||||
|
"db:generate": "drizzle-kit generate",
|
||||||
|
"db:migrate": "drizzle-kit migrate",
|
||||||
|
"db:studio": "drizzle-kit studio"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -14,32 +17,32 @@
|
|||||||
"@nestjs/mapped-types": "*",
|
"@nestjs/mapped-types": "*",
|
||||||
"@nestjs/platform-express": "^10.4.4",
|
"@nestjs/platform-express": "^10.4.4",
|
||||||
"@nestjs/throttler": "^6.2.1",
|
"@nestjs/throttler": "^6.2.1",
|
||||||
"@radix-ui/react-accordion": "^1.2.0",
|
"@radix-ui/react-accordion": "^1.2.1",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.1",
|
"@radix-ui/react-alert-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-aspect-ratio": "^1.1.0",
|
"@radix-ui/react-aspect-ratio": "^1.1.0",
|
||||||
"@radix-ui/react-avatar": "^1.1.0",
|
"@radix-ui/react-avatar": "^1.1.1",
|
||||||
"@radix-ui/react-checkbox": "^1.1.1",
|
"@radix-ui/react-checkbox": "^1.1.2",
|
||||||
"@radix-ui/react-collapsible": "^1.1.0",
|
"@radix-ui/react-collapsible": "^1.1.1",
|
||||||
"@radix-ui/react-context-menu": "^2.2.1",
|
"@radix-ui/react-context-menu": "^2.2.2",
|
||||||
"@radix-ui/react-dialog": "^1.1.1",
|
"@radix-ui/react-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
||||||
"@radix-ui/react-hover-card": "^1.1.1",
|
"@radix-ui/react-hover-card": "^1.1.2",
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
"@radix-ui/react-label": "^2.1.0",
|
||||||
"@radix-ui/react-menubar": "^1.1.1",
|
"@radix-ui/react-menubar": "^1.1.2",
|
||||||
"@radix-ui/react-navigation-menu": "^1.2.0",
|
"@radix-ui/react-navigation-menu": "^1.2.1",
|
||||||
"@radix-ui/react-popover": "^1.1.1",
|
"@radix-ui/react-popover": "^1.1.2",
|
||||||
"@radix-ui/react-progress": "^1.1.0",
|
"@radix-ui/react-progress": "^1.1.0",
|
||||||
"@radix-ui/react-radio-group": "^1.2.0",
|
"@radix-ui/react-radio-group": "^1.2.1",
|
||||||
"@radix-ui/react-scroll-area": "^1.1.0",
|
"@radix-ui/react-scroll-area": "^1.2.0",
|
||||||
"@radix-ui/react-separator": "^1.1.0",
|
"@radix-ui/react-separator": "^1.1.0",
|
||||||
"@radix-ui/react-slider": "^1.2.0",
|
"@radix-ui/react-slider": "^1.2.1",
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@radix-ui/react-switch": "^1.1.0",
|
"@radix-ui/react-switch": "^1.1.1",
|
||||||
"@radix-ui/react-tabs": "^1.1.0",
|
"@radix-ui/react-tabs": "^1.1.1",
|
||||||
"@radix-ui/react-toast": "^1.2.1",
|
"@radix-ui/react-toast": "^1.2.2",
|
||||||
"@radix-ui/react-toggle": "^1.1.0",
|
"@radix-ui/react-toggle": "^1.1.0",
|
||||||
"@radix-ui/react-toggle-group": "^1.1.0",
|
"@radix-ui/react-toggle-group": "^1.1.0",
|
||||||
"@radix-ui/react-tooltip": "^1.1.2",
|
"@radix-ui/react-tooltip": "^1.1.3",
|
||||||
"argon2": "^0.41.1",
|
"argon2": "^0.41.1",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
@ -53,28 +56,29 @@
|
|||||||
"embla-carousel-react": "^8.3.0",
|
"embla-carousel-react": "^8.3.0",
|
||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
"file-type": "^19.5.0",
|
"file-type": "^19.5.0",
|
||||||
"helmet": "^7.1.0",
|
"helmet": "^7.2.0",
|
||||||
"input-otp": "^1.2.4",
|
"input-otp": "^1.2.4",
|
||||||
"jose": "^5.9.3",
|
"jose": "^5.9.3",
|
||||||
"lucide-react": "^0.429.0",
|
"lucide-react": "^0.429.0",
|
||||||
|
"magic-bytes.js": "^1.10.0",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"postgres": "^3.4.4",
|
"postgres": "^3.4.4",
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-day-picker": "^9.1.2",
|
"react-day-picker": "^9.1.3",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
"react-resizable-panels": "^2.1.3",
|
"react-resizable-panels": "^2.1.4",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
"reflect-metadata": "^0.1.14",
|
"reflect-metadata": "^0.1.14",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"sonner": "^1.5.0",
|
"sonner": "^1.5.0",
|
||||||
"tailwind-merge": "^2.5.2",
|
"tailwind-merge": "^2.5.3",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"ts-mockito": "^2.6.1",
|
"ts-mockito": "^2.6.1",
|
||||||
"tslib": "^2.7.0"
|
"tslib": "^2.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.2",
|
"@biomejs/biome": "^1.9.3",
|
||||||
"@nestjs/schematics": "^10.1.4",
|
"@nestjs/schematics": "^10.1.4",
|
||||||
"@nestjs/testing": "^10.4.4",
|
"@nestjs/testing": "^10.4.4",
|
||||||
"@nx/cypress": "19.6.1",
|
"@nx/cypress": "19.6.1",
|
||||||
@ -82,16 +86,16 @@
|
|||||||
"@nx/eslint-plugin": "19.6.1",
|
"@nx/eslint-plugin": "19.6.1",
|
||||||
"@nx/jest": "19.6.1",
|
"@nx/jest": "19.6.1",
|
||||||
"@nx/js": "19.6.1",
|
"@nx/js": "19.6.1",
|
||||||
"@nx/nest": "^19.8.0",
|
"@nx/nest": "^19.8.4",
|
||||||
"@nx/next": "19.6.1",
|
"@nx/next": "19.6.1",
|
||||||
"@nx/node": "19.6.1",
|
"@nx/node": "19.6.1",
|
||||||
"@nx/react": "19.6.1",
|
"@nx/react": "19.6.1",
|
||||||
"@nx/web": "19.6.1",
|
"@nx/web": "19.6.1",
|
||||||
"@nx/webpack": "19.6.1",
|
"@nx/webpack": "19.6.1",
|
||||||
"@nx/workspace": "19.6.1",
|
"@nx/workspace": "19.6.1",
|
||||||
"@swc-node/register": "~1.9.2",
|
"@swc-node/register": "~1.10.9",
|
||||||
"@swc/cli": "~0.3.14",
|
"@swc/cli": "~0.3.14",
|
||||||
"@swc/core": "~1.5.29",
|
"@swc/core": "~1.7.26",
|
||||||
"@swc/helpers": "~0.5.13",
|
"@swc/helpers": "~0.5.13",
|
||||||
"@types/jest": "^29.5.13",
|
"@types/jest": "^29.5.13",
|
||||||
"@types/node": "18.16.9",
|
"@types/node": "18.16.9",
|
||||||
@ -101,7 +105,7 @@
|
|||||||
"@typescript-eslint/parser": "^7.18.0",
|
"@typescript-eslint/parser": "^7.18.0",
|
||||||
"autoprefixer": "10.4.13",
|
"autoprefixer": "10.4.13",
|
||||||
"babel-jest": "^29.7.0",
|
"babel-jest": "^29.7.0",
|
||||||
"cypress": "^13.14.2",
|
"cypress": "^13.15.0",
|
||||||
"eslint": "~8.57.1",
|
"eslint": "~8.57.1",
|
||||||
"eslint-config-next": "14.2.3",
|
"eslint-config-next": "14.2.3",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
@ -118,7 +122,7 @@
|
|||||||
"tailwindcss": "3.4.3",
|
"tailwindcss": "3.4.3",
|
||||||
"ts-jest": "^29.2.5",
|
"ts-jest": "^29.2.5",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"typescript": "~5.5.4",
|
"typescript": "~5.6.2",
|
||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1674
pnpm-lock.yaml
generated
1674
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user