Add Swagger integration and console logging for debugging

Integrated Swagger module in the backend for API documentation. Added console logs for better traceability and debugging in service and controller methods.
This commit is contained in:
Mathis H (Avnyr) 2024-10-15 15:15:55 +02:00
parent 6f0f209e00
commit ff649ebdbf
Signed by: Mathis
GPG Key ID: DD9E0666A747D126
9 changed files with 403 additions and 351 deletions

View File

@ -16,14 +16,13 @@ import { UserGuard } from "./auth.guard";
@Controller("auth") @Controller("auth")
export class AuthController { export class AuthController {
constructor(private readonly authService: AuthService) {} constructor(private readonly authService: AuthService) { }
//TODO Initial account validation for admin privileges //TODO Initial account validation for admin privileges
//POST signup //POST signup
@HttpCode(HttpStatus.CREATED) @HttpCode(HttpStatus.CREATED)
@Post("signup") @Post("signup")
async signUp(@Body() dto: SignUpDto) { async signUp(@Body() dto: SignUpDto) {
console.log(dto);
return this.authService.doRegister(dto); return this.authService.doRegister(dto);
} }
@ -31,7 +30,6 @@ export class AuthController {
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post("signin") @Post("signin")
async signIn(@Body() dto: SignInDto) { async signIn(@Body() dto: SignInDto) {
console.log(dto);
return this.authService.doLogin(dto); return this.authService.doLogin(dto);
} }
//GET me -- Get current user data via jwt //GET me -- Get current user data via jwt

View File

@ -31,7 +31,6 @@ export class SignUpDto {
@IsNotEmpty() @IsNotEmpty()
@IsStrongPassword({ @IsStrongPassword({
minLength: 6, minLength: 6,
minSymbols: 1,
}) })
password: string; password: string;
} }
@ -46,7 +45,6 @@ export class SignInDto {
@IsNotEmpty() @IsNotEmpty()
@IsStrongPassword({ @IsStrongPassword({
minLength: 6, minLength: 6,
minSymbols: 1,
}) })
password: string; password: string;
} }

View File

@ -14,11 +14,10 @@ export class AuthService implements OnModuleInit {
constructor( constructor(
private db: DbService, private db: DbService,
private credentials: CredentialsService, private credentials: CredentialsService,
) {} ) { }
//TODO Initial account validation for admin privileges //TODO Initial account validation for admin privileges
async doRegister(data: SignUpDto) { async doRegister(data: SignUpDto) {
console.log(data);
const existingUser = await this.db const existingUser = await this.db
.use() .use()
.select() .select()

View File

@ -6,10 +6,9 @@ import { JWTPayload, generateSecret } from "jose";
@Injectable() @Injectable()
export class CredentialsService { export class CredentialsService {
constructor(private readonly configService: ConfigService) {} constructor(private readonly configService: ConfigService) { }
async hash(plaintextPassword: string) { async hash(plaintextPassword: string) {
console.log(plaintextPassword);
if (plaintextPassword.length < 6) if (plaintextPassword.length < 6)
throw new BadRequestException("Password is not strong enough !"); throw new BadRequestException("Password is not strong enough !");
return argon.hash(plaintextPassword, { return argon.hash(plaintextPassword, {

View File

@ -26,7 +26,7 @@ import { FilesService } from "./files.service";
@Controller("files") @Controller("files")
export class FilesController { export class FilesController {
constructor(private readonly filesService: FilesService) {} constructor(private readonly filesService: FilesService) { }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@UseGuards(InsertAdminState) @UseGuards(InsertAdminState)
@ -120,22 +120,10 @@ export class FilesController {
return this.filesService.search(limit, offset, search); return this.filesService.search(limit, offset, search);
} }
@HttpCode(HttpStatus.FOUND)
@Get(":fileId")
async getFile(@Param("fileId") fileId: string) {
return await this.filesService.get(fileId);
}
@HttpCode(HttpStatus.OK)
@UseGuards(AdminGuard)
@Delete(":fileId")
async deleteFile(@Param("fileId", ParseUUIDPipe) fileId: string) {
return await this.filesService.deleteFile(fileId);
}
@HttpCode(HttpStatus.FOUND) @HttpCode(HttpStatus.FOUND)
@Get("types") @Get("types")
async getTypes() { async getTypes() {
console.log("Performing request")
return await this.filesService.getAllFilesTypes(); return await this.filesService.getAllFilesTypes();
} }
@ -150,6 +138,20 @@ export class FilesController {
@UseGuards(AdminGuard) @UseGuards(AdminGuard)
@Delete("types/:typeId") @Delete("types/:typeId")
async delType(@Param(":typeId", ParseUUIDPipe) typeId: string) { async delType(@Param(":typeId", ParseUUIDPipe) typeId: string) {
//TODO return await this.filesService.removeFileType(typeId)
} }
@HttpCode(HttpStatus.FOUND)
@Get(":fileId")
async getFile(@Param("fileId") fileId: string) {
return await this.filesService.get(fileId);
}
@HttpCode(HttpStatus.OK)
@UseGuards(AdminGuard)
@Delete(":fileId")
async deleteFile(@Param("fileId", ParseUUIDPipe) fileId: string) {
return await this.filesService.deleteFile(fileId);
}
} }

View File

@ -293,12 +293,14 @@ export class FilesService {
* @return {Promise<Array>} Promise that resolves to an array of file types. * @return {Promise<Array>} Promise that resolves to an array of file types.
*/ */
public async getAllFilesTypes(): Promise<Array<object>> { public async getAllFilesTypes(): Promise<Array<object>> {
return await this.database const result = await this.database
.use() .use()
.select() .select()
.from(FilesTypesTable) .from(FilesTypesTable)
.prepare("getAllFilesTypes") .prepare("getAllFilesTypes")
.execute(); .execute();
console.log(result)
return result;
} }
/** /**

View File

@ -1,20 +1,28 @@
/**
* This is not a production server yet!
* This is only a minimal backend to get started.
*/
import { Logger } from "@nestjs/common"; import { Logger } from "@nestjs/common";
import { NestFactory } from "@nestjs/core"; import { NestFactory } from "@nestjs/core";
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import helmet from "helmet"; import helmet from "helmet";
import { AppModule } from "./app/app.module"; import { AppModule } from "./app/app.module";
async function bootstrap() { async function bootstrap() {
const config = new DocumentBuilder()
.setTitle('Fab Explorer')
.setDescription("Définition de l'api du FabLab Explorer")
.setVersion('1.0')
.build();
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
const globalPrefix = "api"; const globalPrefix = "api";
app.setGlobalPrefix(globalPrefix); app.setGlobalPrefix(globalPrefix);
app.use(helmet()); app.use(helmet());
const port = process.env.PORT || 3000; const port = process.env.PORT || 3000;
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(port); await app.listen(port);
Logger.log( Logger.log(
`🚀 Application is running on: http://localhost:${port}/${globalPrefix}`, `🚀 Application is running on: http://localhost:${port}/${globalPrefix}`,

View File

@ -17,6 +17,7 @@
"@nestjs/core": "^10.4.4", "@nestjs/core": "^10.4.4",
"@nestjs/mapped-types": "*", "@nestjs/mapped-types": "*",
"@nestjs/platform-express": "^10.4.4", "@nestjs/platform-express": "^10.4.4",
"@nestjs/swagger": "^7.4.2",
"@nestjs/throttler": "^6.2.1", "@nestjs/throttler": "^6.2.1",
"@radix-ui/react-accordion": "^1.2.1", "@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-alert-dialog": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.1.2",

45
pnpm-lock.yaml generated
View File

@ -26,6 +26,9 @@ importers:
'@nestjs/platform-express': '@nestjs/platform-express':
specifier: ^10.4.4 specifier: ^10.4.4
version: 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4) version: 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4)
'@nestjs/swagger':
specifier: ^7.4.2
version: 7.4.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)
'@nestjs/throttler': '@nestjs/throttler':
specifier: ^6.2.1 specifier: ^6.2.1
version: 6.2.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14) version: 6.2.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)
@ -1582,6 +1585,9 @@ packages:
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
engines: {node: '>=8'} engines: {node: '>=8'}
'@microsoft/tsdoc@0.15.0':
resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==}
'@module-federation/bridge-react-webpack-plugin@0.2.8': '@module-federation/bridge-react-webpack-plugin@0.2.8':
resolution: {integrity: sha512-6G1qTo1HWvRcN5fzE+SZgvgzSPoq5YqNx8hFL8BttJmnd3wj4SUOFiikAsXhdVrzSK+Zuzg6pipkiLH1m+pbtw==} resolution: {integrity: sha512-6G1qTo1HWvRcN5fzE+SZgvgzSPoq5YqNx8hFL8BttJmnd3wj4SUOFiikAsXhdVrzSK+Zuzg6pipkiLH1m+pbtw==}
@ -1712,6 +1718,23 @@ packages:
peerDependencies: peerDependencies:
typescript: '>=4.3.5' typescript: '>=4.3.5'
'@nestjs/swagger@7.4.2':
resolution: {integrity: sha512-Mu6TEn1M/owIvAx2B4DUQObQXqo2028R2s9rSZ/hJEgBK95+doTwS0DjmVA2wTeZTyVtXOoN7CsoM5pONBzvKQ==}
peerDependencies:
'@fastify/static': ^6.0.0 || ^7.0.0
'@nestjs/common': ^9.0.0 || ^10.0.0
'@nestjs/core': ^9.0.0 || ^10.0.0
class-transformer: '*'
class-validator: '*'
reflect-metadata: ^0.1.12 || ^0.2.0
peerDependenciesMeta:
'@fastify/static':
optional: true
class-transformer:
optional: true
class-validator:
optional: true
'@nestjs/testing@10.4.4': '@nestjs/testing@10.4.4':
resolution: {integrity: sha512-qRGFj51A5RM7JqA8pcyEwSLA3Y0dle/PAZ8oxP0suimoCusRY3Tk7wYqutZdCNj1ATb678SDaUZDHk2pwSv9/g==} resolution: {integrity: sha512-qRGFj51A5RM7JqA8pcyEwSLA3Y0dle/PAZ8oxP0suimoCusRY3Tk7wYqutZdCNj1ATb678SDaUZDHk2pwSv9/g==}
peerDependencies: peerDependencies:
@ -7894,6 +7917,9 @@ packages:
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
swagger-ui-dist@5.17.14:
resolution: {integrity: sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==}
symbol-tree@3.2.4: symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
@ -9971,6 +9997,8 @@ snapshots:
'@lukeed/csprng@1.1.0': {} '@lukeed/csprng@1.1.0': {}
'@microsoft/tsdoc@0.15.0': {}
'@module-federation/bridge-react-webpack-plugin@0.2.8': '@module-federation/bridge-react-webpack-plugin@0.2.8':
dependencies: dependencies:
'@module-federation/sdk': 0.2.8 '@module-federation/sdk': 0.2.8
@ -10171,6 +10199,21 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- chokidar - chokidar
'@nestjs/swagger@7.4.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)':
dependencies:
'@microsoft/tsdoc': 0.15.0
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
'@nestjs/core': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1)
'@nestjs/mapped-types': 2.0.5(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)
js-yaml: 4.1.0
lodash: 4.17.21
path-to-regexp: 3.3.0
reflect-metadata: 0.1.14
swagger-ui-dist: 5.17.14
optionalDependencies:
class-transformer: 0.5.1
class-validator: 0.14.1
'@nestjs/testing@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4))': '@nestjs/testing@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4))':
dependencies: dependencies:
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
@ -17863,6 +17906,8 @@ snapshots:
csso: 5.0.5 csso: 5.0.5
picocolors: 1.0.1 picocolors: 1.0.1
swagger-ui-dist@5.17.14: {}
symbol-tree@3.2.4: {} symbol-tree@3.2.4: {}
tailwind-merge@2.5.3: {} tailwind-merge@2.5.3: {}