From 5e6974d6c5a6e3088cbb091818993f4ddd4bb877 Mon Sep 17 00:00:00 2001 From: Viachaslau Tyshkavets Date: Mon, 2 Sep 2024 19:28:43 +0400 Subject: [PATCH] chore: unify prettier configs between back-end and front-end --- .prettierrc | 3 +- client/.prettierrc | 12 +- client/index.html | 66 +--- client/src/api/httpClient.ts | 6 +- docker-compose.local.yml | 2 +- docker-compose.yml | 4 +- eslint.config.mjs | 12 +- src/app.controller.ts | 78 ++--- src/app.module.config.properties.ts | 2 +- src/app.module.ts | 10 +- src/app.resolver.ts | 2 +- src/app.service.ts | 20 +- src/auth/api/LoginJwtResponse.ts | 2 +- src/auth/api/LoginResponse.ts | 2 +- src/auth/api/login.request.ts | 4 +- src/auth/auth.controller.spec.ts | 10 +- src/auth/auth.controller.ts | 286 +++++++++--------- src/auth/auth.guard.ts | 12 +- src/auth/auth.module.config.properties.ts | 2 +- src/auth/auth.module.ts | 4 +- src/auth/auth.service.spec.ts | 22 +- src/auth/auth.service.ts | 48 +-- src/auth/credentials.utils.ts | 2 +- src/auth/csrf.guard.ts | 4 +- src/auth/jwt/jwt.token.bearer.processor.ts | 10 +- src/auth/jwt/jwt.token.processor.ts | 4 +- .../jwt/jwt.token.with.hmac.keys.processor.ts | 2 +- src/auth/jwt/jwt.token.with.jku.processor.ts | 4 +- src/auth/jwt/jwt.token.with.jwk.processor.ts | 4 +- .../jwt/jwt.token.with.rsa.keys.processor.ts | 2 +- ...token.with.rsa.signature.keys.processor.ts | 2 +- .../jwt/jwt.token.with.sql.kid.processor.ts | 8 +- .../jwt/jwt.token.with.x5c.key.processor.ts | 2 +- .../jwt/jwt.token.with.x5u.key.processor.ts | 4 +- src/chat/api/ChatMessage.ts | 4 +- src/chat/chat.controller.ts | 8 +- src/chat/chat.module.ts | 2 +- src/chat/chat.service.ts | 10 +- src/components/any-files.interceptor.ts | 8 +- src/components/global-exception.filter.ts | 6 +- .../headers.configurator.interceptor.ts | 12 +- src/email/email.controller.ts | 26 +- src/email/email.module.ts | 2 +- src/email/email.service.ts | 28 +- src/file/cloud.providers.metadata.ts | 12 +- src/file/file.controller.spec.ts | 6 +- src/file/file.controller.ts | 112 +++---- src/file/file.module.ts | 2 +- src/file/file.service.spec.ts | 2 +- src/httpclient/httpclient.module.ts | 2 +- src/httpclient/httpclient.service.spec.ts | 2 +- src/httpclient/httpclient.service.ts | 12 +- src/keycloak/keycloak.config.properties.ts | 2 +- src/keycloak/keycloak.module.ts | 2 +- src/keycloak/keycloak.service.ts | 66 ++-- src/main.ts | 44 +-- src/model/user.entity.ts | 2 +- src/orm/orm.config.factory.ts | 14 +- src/orm/orm.module.config.properties.ts | 2 +- src/orm/orm.module.ts | 8 +- src/partners/partners.controller.ts | 36 +-- src/partners/partners.module.ts | 2 +- src/partners/partners.service.spec.ts | 2 +- src/partners/partners.service.ts | 6 +- src/products/api/ProductDto.ts | 2 +- src/products/products.controller.ts | 36 +-- src/products/products.module.ts | 2 +- src/products/products.resolver.ts | 10 +- src/products/products.service.ts | 14 +- .../subscriptions.controller.spec.ts | 2 +- src/subscriptions/subscriptions.controller.ts | 8 +- src/subscriptions/subscriptions.module.ts | 2 +- src/testimonials/api/TestimonialDto.ts | 2 +- .../testimonials.controller.spec.ts | 8 +- src/testimonials/testimonials.controller.ts | 36 +-- src/testimonials/testimonials.module.ts | 2 +- src/testimonials/testimonials.resolver.ts | 18 +- src/testimonials/testimonials.service.spec.ts | 8 +- src/testimonials/testimonials.service.ts | 10 +- src/users/api/CreateUserRequest.ts | 2 +- src/users/users.controller.spec.ts | 10 +- src/users/users.controller.ts | 164 +++++----- src/users/users.module.ts | 2 +- src/users/users.service.spec.ts | 8 +- src/users/users.service.ts | 16 +- src/utils/url.ts | 2 +- test/auth.e2e-spec.ts | 16 +- test/config.e2e-spec.ts | 14 +- test/jest-e2e.config.mjs | 2 +- test/metadata.e2e-spec.ts | 4 +- test/render.e2e-spec.ts | 4 +- test/root.e2e-spec.ts | 6 +- test/spawn.e2e-spec.ts | 2 +- test/testimonials.e2e-spec.ts | 2 +- 94 files changed, 737 insertions(+), 776 deletions(-) diff --git a/.prettierrc b/.prettierrc index a20502b7..268c7f2d 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { + "tabWidth": 2, "singleQuote": true, - "trailingComma": "all" + "trailingComma": "none" } diff --git a/client/.prettierrc b/client/.prettierrc index c6c0c913..f9715055 100644 --- a/client/.prettierrc +++ b/client/.prettierrc @@ -1,9 +1,13 @@ { "tabWidth": 2, "singleQuote": true, - "bracketSpacing": true, - "printWidth": 80, "trailingComma": "none", - "arrowParens": "always", - "quoteProps": "consistent" + "overrides": [ + { + "files": ["*.html", "*.md"], + "options": { + "printWidth": 120 + } + } + ] } diff --git a/client/index.html b/client/index.html index b63180f2..b12f71a2 100644 --- a/client/index.html +++ b/client/index.html @@ -6,34 +6,12 @@ - - - - + + + + - + - + - + - - - + + + - + diff --git a/client/src/api/httpClient.ts b/client/src/api/httpClient.ts index 1695a157..a477ea7f 100644 --- a/client/src/api/httpClient.ts +++ b/client/src/api/httpClient.ts @@ -215,7 +215,7 @@ export function putUserData(user: UserData): Promise { method: 'put', headers: { 'content-type': 'application/json', - 'authorization': + authorization: sessionStorage.getItem('token') || localStorage.getItem('token') }, data: user @@ -231,7 +231,7 @@ export function putPhoto(photo: File, email: string): Promise { method: 'put', headers: { 'content-type': 'image/png', - 'authorization': + authorization: sessionStorage.getItem('token') || localStorage.getItem('token') }, data @@ -287,7 +287,7 @@ export function viewProduct(productName: string): Promise { url: `${ApiUrl.Products}/views`, method: 'get', headers: { - 'authorization': + authorization: sessionStorage.getItem('token') || localStorage.getItem('token'), 'x-product-name': productName } diff --git a/docker-compose.local.yml b/docker-compose.local.yml index caba2d0a..bbf3c28f 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -14,7 +14,7 @@ services: '-U', '${POSTGRES_USER}', '-P', - '${POSTGRES_PASSWORD}', + '${POSTGRES_PASSWORD}' ] timeout: 45s environment: diff --git a/docker-compose.yml b/docker-compose.yml index 83d9cad2..95591210 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,7 @@ services: '-U', '${POSTGRES_USER}', '-P', - '${POSTGRES_PASSWORD}', + '${POSTGRES_PASSWORD}' ] timeout: 45s volumes: @@ -69,7 +69,7 @@ services: '-U', '${POSTGRES_USER}', '-P', - '${POSTGRES_PASSWORD}', + '${POSTGRES_PASSWORD}' ] timeout: 45s restart: on-failure diff --git a/eslint.config.mjs b/eslint.config.mjs index 024b53f2..8f2958e0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,16 +5,16 @@ export default tseslint.config( eslint.configs.recommended, ...tseslint.configs.strict, { - ignores: ['**/charts', '**/dist', '**/client'], + ignores: ['**/charts', '**/dist', '**/client'] }, { rules: { '@typescript-eslint/no-extraneous-class': [ 'error', { - allowWithDecorator: true, - }, - ], - }, - }, + allowWithDecorator: true + } + ] + } + } ); diff --git a/src/app.controller.ts b/src/app.controller.ts index fb6403dd..72b96269 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -17,7 +17,7 @@ import { UseInterceptors, ParseIntPipe, DefaultValuePipe, - HttpStatus, + HttpStatus } from '@nestjs/common'; import { ApiBody, @@ -29,7 +29,7 @@ import { ApiOperation, ApiProduces, ApiQuery, - ApiTags, + ApiTags } from '@nestjs/swagger'; import * as dotT from 'dot'; import { parseXml } from 'libxmljs'; @@ -42,7 +42,7 @@ import { API_DESC_RENDER_REQUEST, API_DESC_XML_METADATA, SWAGGER_DESC_SECRETS, - SWAGGER_DESC_NESTED_JSON, + SWAGGER_DESC_NESTED_JSON } from './app.controller.swagger.desc'; import { AuthGuard } from './auth/auth.guard'; import { JwtType } from './auth/jwt/jwt.type.decorator'; @@ -62,11 +62,11 @@ export class AppController { @ApiProduces('text/plain') @ApiConsumes('text/plain') @ApiOperation({ - description: API_DESC_RENDER_REQUEST, + description: API_DESC_RENDER_REQUEST }) @ApiBody({ description: 'Write your text here' }) @ApiCreatedResponse({ - description: 'Rendered result', + description: 'Rendered result' }) async renderTemplate(@Body() raw): Promise { if (typeof raw === 'string' || Buffer.isBuffer(raw)) { @@ -80,10 +80,10 @@ export class AppController { @Get('goto') @ApiQuery({ name: 'url', example: 'https://google.com', required: true }) @ApiOperation({ - description: API_DESC_REDIRECT_REQUEST, + description: API_DESC_REDIRECT_REQUEST }) @ApiOkResponse({ - description: 'Redirected', + description: 'Redirected' }) @Redirect() async redirect(@Query('url') url: string) { @@ -98,25 +98,25 @@ export class AppController { examples: { xml_doc: { summary: 'XML doc', - value: ``, - }, - }, + value: `` + } + } }) @ApiOperation({ - description: API_DESC_XML_METADATA, + description: API_DESC_XML_METADATA }) @ApiInternalServerErrorResponse({ - description: 'Invalid data', + description: 'Invalid data' }) @ApiCreatedResponse({ - description: 'XML passed successfully', + description: 'XML passed successfully' }) @Header('content-type', 'text/xml') async xml(@Body() xml: string): Promise { const xmlDoc = parseXml(decodeURIComponent(xml), { noent: true, dtdvalid: true, - recover: true, + recover: true }); this.logger.debug(xmlDoc); this.logger.debug(xmlDoc.getDtd()); @@ -126,7 +126,7 @@ export class AppController { @Options() @ApiOperation({ - description: API_DESC_OPTIONS_REQUEST, + description: API_DESC_OPTIONS_REQUEST }) @Header('allow', 'OPTIONS, GET, HEAD, POST') async getTestOptions(): Promise { @@ -136,16 +136,16 @@ export class AppController { @Get('spawn') @ApiQuery({ name: 'command', example: 'ls -la', required: true }) @ApiOperation({ - description: API_DESC_LAUNCH_COMMAND, + description: API_DESC_LAUNCH_COMMAND }) @ApiOkResponse({ - type: String, + type: String }) @ApiInternalServerErrorResponse({ schema: { type: 'object', - properties: { location: { type: 'string' } }, - }, + properties: { location: { type: 'string' } } + } }) async getCommandResult(@Query('command') command: string): Promise { this.logger.debug(`launch ${command} command`); @@ -154,18 +154,18 @@ export class AppController { } catch (err) { throw new InternalServerErrorException({ error: err.message || err, - location: __filename, + location: __filename }); } } @Get('/config') @ApiOperation({ - description: API_DESC_CONFIG_SERVER, + description: API_DESC_CONFIG_SERVER }) @ApiOkResponse({ type: AppConfig, - status: 200, + status: 200 }) getConfig(): AppConfig { this.logger.debug('Called getConfig'); @@ -175,11 +175,11 @@ export class AppController { @Get('/secrets') @ApiOperation({ - description: SWAGGER_DESC_SECRETS, + description: SWAGGER_DESC_SECRETS }) @ApiOkResponse({ type: Object, - status: 200, + status: 200 }) getSecrets(): Record { const secrets = { @@ -200,7 +200,7 @@ export class AppController { paypal: 'access_token$production$x0lb4r69dvmmnufd$3ea7cb281754b7da7dac131ef5783321', slack: - 'xoxo-175588824543-175748345725-176608801663-826315f84e553d482bb7e73e8322sdf3', + 'xoxo-175588824543-175748345725-176608801663-826315f84e553d482bb7e73e8322sdf3' }; return secrets; } @@ -210,11 +210,11 @@ export class AppController { @UseInterceptors(ClassSerializerInterceptor) @SerializeOptions({ groups: [BASIC_USER_INFO] }) @ApiOperation({ - description: SWAGGER_DESC_FIND_USER, + description: SWAGGER_DESC_FIND_USER }) @ApiOkResponse({ type: UserDto, - description: 'Returns basic user info if it exists', + description: 'Returns basic user info if it exists' }) @ApiNotFoundResponse({ description: 'User not found', @@ -222,9 +222,9 @@ export class AppController { type: 'object', properties: { statusCode: { type: 'number' }, - message: { type: 'string' }, - }, - }, + message: { type: 'string' } + } + } }) async getUserInfo(@Param('email') email: string): Promise { try { @@ -241,11 +241,11 @@ export class AppController { @UseInterceptors(ClassSerializerInterceptor) @SerializeOptions({ groups: [BASIC_USER_INFO] }) @ApiOperation({ - description: SWAGGER_DESC_FIND_USER, + description: SWAGGER_DESC_FIND_USER }) @ApiOkResponse({ type: UserDto, - description: 'Returns basic user info if it exists', + description: 'Returns basic user info if it exists' }) @ApiNotFoundResponse({ description: 'User not found', @@ -253,9 +253,9 @@ export class AppController { type: 'object', properties: { statusCode: { type: 'number' }, - message: { type: 'string' }, - }, - }, + message: { type: 'string' } + } + } }) async getUserInfoV2(@Param('email') email: string): Promise { try { @@ -267,21 +267,21 @@ export class AppController { @Get('nestedJson') @ApiOperation({ - description: SWAGGER_DESC_NESTED_JSON, + description: SWAGGER_DESC_NESTED_JSON }) @Header('content-type', 'application/json') async getNestedJson( @Query( 'depth', new DefaultValuePipe(1), - new ParseIntPipe({ errorHttpStatusCode: HttpStatus.BAD_REQUEST }), + new ParseIntPipe({ errorHttpStatusCode: HttpStatus.BAD_REQUEST }) ) - depth: number, + depth: number ): Promise { if (depth < 1) { throw new HttpException( 'JSON nesting depth is invalid', - HttpStatus.BAD_REQUEST, + HttpStatus.BAD_REQUEST ); } diff --git a/src/app.module.config.properties.ts b/src/app.module.config.properties.ts index e49bc6df..756294e7 100644 --- a/src/app.module.config.properties.ts +++ b/src/app.module.config.properties.ts @@ -1,4 +1,4 @@ export enum AppModuleConfigProperties { ENV_AWS_BUCKET = 'AWS_BUCKET', - ENV_GOOGLE_MAPS = 'GOOGLE_MAPS_API', + ENV_GOOGLE_MAPS = 'GOOGLE_MAPS_API' } diff --git a/src/app.module.ts b/src/app.module.ts index 19c765fb..b7aba652 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -30,17 +30,17 @@ import { ChatModule } from './chat/chat.module'; TestimonialsModule, ProductsModule, ConfigModule.forRoot({ - isGlobal: true, + isGlobal: true }), HttpClientModule, GraphQLModule.forRoot({ driver: MercuriusDriver, graphiql: true, - autoSchemaFile: true, + autoSchemaFile: true }), PartnersModule, EmailModule, - ChatModule, + ChatModule ], controllers: [AppController], providers: [ @@ -48,8 +48,8 @@ import { ChatModule } from './chat/chat.module'; AppService, UsersService, ConfigService, - AppResolver, - ], + AppResolver + ] }) export class AppModule { configure(consumer: MiddlewareConsumer) { diff --git a/src/app.resolver.ts b/src/app.resolver.ts index 8d2e8a63..c901b8c6 100644 --- a/src/app.resolver.ts +++ b/src/app.resolver.ts @@ -11,7 +11,7 @@ export class AppResolver { constructor(private readonly appService: AppService) {} @Query(() => String, { - description: API_DESC_LAUNCH_COMMAND, + description: API_DESC_LAUNCH_COMMAND }) async getCommandResult(@Args('command') command: string): Promise { this.logger.debug(`launch ${command} command`); diff --git a/src/app.service.ts b/src/app.service.ts index 633f272c..1d10e0f5 100644 --- a/src/app.service.ts +++ b/src/app.service.ts @@ -13,7 +13,7 @@ export class AppService { constructor( private readonly configService: ConfigService, - private readonly userService: UsersService, + private readonly userService: UsersService ) {} async launchCommand(command: string): Promise { @@ -37,7 +37,7 @@ export class AppService { ps.on('error', (err) => rej(err.message)); ps.on('close', (code) => - this.logger.debug(`child process exited with code ${code}`), + this.logger.debug(`child process exited with code ${code}`) ); } catch (err) { rej(err.message); @@ -48,29 +48,29 @@ export class AppService { getConfig(): AppConfig { this.logger.debug('Called getConfig'); const dbSchema = this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_SCHEMA, + OrmModuleConfigProperties.ENV_DATABASE_SCHEMA ), dbHost = this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_HOST, + OrmModuleConfigProperties.ENV_DATABASE_HOST ), dbPort = this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_PORT, + OrmModuleConfigProperties.ENV_DATABASE_PORT ), dbUser = this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_USER, + OrmModuleConfigProperties.ENV_DATABASE_USER ), dbPwd = this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_PASSWORD, + OrmModuleConfigProperties.ENV_DATABASE_PASSWORD ); return { awsBucket: this.configService.get( - AppModuleConfigProperties.ENV_AWS_BUCKET, + AppModuleConfigProperties.ENV_AWS_BUCKET ), sql: `postgres://${dbUser}:${dbPwd}@${dbHost}:${dbPort}/${dbSchema} `, googlemaps: this.configService.get( - AppModuleConfigProperties.ENV_GOOGLE_MAPS, - ), + AppModuleConfigProperties.ENV_GOOGLE_MAPS + ) }; } diff --git a/src/auth/api/LoginJwtResponse.ts b/src/auth/api/LoginJwtResponse.ts index e68d25a2..6aae40d4 100644 --- a/src/auth/api/LoginJwtResponse.ts +++ b/src/auth/api/LoginJwtResponse.ts @@ -8,7 +8,7 @@ export class LoginJwtResponse { email: string; @ApiProperty({ - description: 'ldap query link for user details', + description: 'ldap query link for user details' }) ldapProfileLink: string; } diff --git a/src/auth/api/LoginResponse.ts b/src/auth/api/LoginResponse.ts index a2cb7c78..be2814c0 100644 --- a/src/auth/api/LoginResponse.ts +++ b/src/auth/api/LoginResponse.ts @@ -5,7 +5,7 @@ export class LoginResponse { email: string; @ApiProperty({ - description: 'ldap query link for user details', + description: 'ldap query link for user details' }) ldapProfileLink: string; } diff --git a/src/auth/api/login.request.ts b/src/auth/api/login.request.ts index cf45ad27..31636eb2 100644 --- a/src/auth/api/login.request.ts +++ b/src/auth/api/login.request.ts @@ -5,7 +5,7 @@ export enum FormMode { HTML = 'html', CSRF = 'csrf', DOM_BASED_CSRF = 'csrf_dom', - OIDC = 'oidc', + OIDC = 'oidc' } export class LoginRequest { @@ -17,7 +17,7 @@ export class LoginRequest { @ApiProperty({ enum: FormMode, - required: true, + required: true }) op?: string; diff --git a/src/auth/auth.controller.spec.ts b/src/auth/auth.controller.spec.ts index 71bebf1f..9376537b 100644 --- a/src/auth/auth.controller.spec.ts +++ b/src/auth/auth.controller.spec.ts @@ -13,17 +13,17 @@ describe('AuthController', () => { providers: [ { provide: UsersService, - useValue: {}, + useValue: {} }, { provide: KeyCloakService, - useValue: {}, + useValue: {} }, { provide: AuthService, - useValue: {}, - }, - ], + useValue: {} + } + ] }).compile(); controller = module.get(AuthController); diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index aec83b01..6f5aaef7 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -11,7 +11,7 @@ import { Req, Res, UnauthorizedException, - UseGuards, + UseGuards } from '@nestjs/common'; import { createHash, randomBytes } from 'crypto'; import { @@ -21,7 +21,7 @@ import { ApiOperation, ApiResponse, ApiTags, - ApiUnauthorizedResponse, + ApiUnauthorizedResponse } from '@nestjs/swagger'; import { User } from '../model/user.entity'; import { LdapQueryHandler } from '../users/ldap.query.handler'; @@ -49,7 +49,7 @@ import { SWAGGER_DESC_REQUEST_WITH_SIMPLE_CSRF_TOKEN, SWAGGER_DESC_LOGIN_WITH_HMAC_JWT, SWAGGER_DESC_VALIDATE_WITH_HMAC_JWT, - SWAGGER_DESC_VALIDATE_WITH_RSA_SIGNATURE_JWT, + SWAGGER_DESC_VALIDATE_WITH_RSA_SIGNATURE_JWT } from './auth.controller.swagger.desc'; import { AuthGuard } from './auth.guard'; import { AuthService, JwtProcessorType } from './auth.service'; @@ -75,29 +75,29 @@ export class AuthController { constructor( private readonly usersService: UsersService, private readonly keyCloakService: KeyCloakService, - private readonly authService: AuthService, + private readonly authService: AuthService ) {} @Post('/admin/login') @ApiCreatedResponse({ - type: LoginResponse, + type: LoginResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_RSA_JWT_KEYS, + description: SWAGGER_DESC_LOGIN_WITH_RSA_JWT_KEYS }) async loginWithRSAJwtKeysAdmin( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithRSAJwtKeysAdmin'); return this.loginWithRSAJwtKeys(req, res); @@ -106,24 +106,24 @@ export class AuthController { @Post('login') @UseGuards(CsrfGuard) @ApiCreatedResponse({ - type: LoginResponse, + type: LoginResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_RSA_JWT_KEYS, + description: SWAGGER_DESC_LOGIN_WITH_RSA_JWT_KEYS }) async loginWithRSAJwtKeys( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithRSAJwtKeys'); @@ -146,7 +146,7 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA_SIGNATURE) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -154,22 +154,22 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_RSA_SIGNATURE_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_RSA_SIGNATURE_JWT }) async validateWithRSASignatureJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @Get('dom-csrf-flow') @ApiOperation({ - description: SWAGGER_DESC_REQUEST_WITH_DOM_CSRF_TOKEN, + description: SWAGGER_DESC_REQUEST_WITH_DOM_CSRF_TOKEN }) @ApiBadRequestResponse({ description: 'Bad request, fingerprint is required', @@ -178,13 +178,13 @@ export class AuthController { properties: { statusCode: { type: 'number' }, message: { type: 'string' }, - error: { type: 'string' }, - }, - }, + error: { type: 'string' } + } + } }) async getDomCsrfToken( @Req() request: FastifyRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call getDomCsrfToken'); @@ -197,7 +197,7 @@ export class AuthController { res.setCookie(this.CSRF_COOKIE_HEADER, token, { httpOnly: true, - sameSite: 'strict', + sameSite: 'strict' }); return token; @@ -205,20 +205,20 @@ export class AuthController { @Get('simple-csrf-flow') @ApiOperation({ - description: SWAGGER_DESC_REQUEST_WITH_SIMPLE_CSRF_TOKEN, + description: SWAGGER_DESC_REQUEST_WITH_SIMPLE_CSRF_TOKEN }) @ApiOkResponse({ - description: 'Returns simple csrf token', + description: 'Returns simple csrf token' }) async getCsrfToken( - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call getCsrfToken'); const token = randomBytes(32).toString('base64').substring(0, 32); res.setCookie(this.CSRF_COOKIE_HEADER, token, { httpOnly: true, - sameSite: 'strict', + sameSite: 'strict' }); return token; } @@ -226,10 +226,10 @@ export class AuthController { @Get('oidc-client') @ApiResponse({ type: OidcClientResponse, - status: HttpStatus.OK, + status: HttpStatus.OK }) @ApiOperation({ - description: SWAGGER_DESC_CALL_OIDC_CLIENT, + description: SWAGGER_DESC_CALL_OIDC_CLIENT }) async getOidcClient(): Promise { this.logger.debug('Call getOidcClient'); @@ -239,30 +239,30 @@ export class AuthController { return { clientId: client.client_id, clientSecret: client.client_secret, - metadataUrl: client.metadata_url, + metadataUrl: client.metadata_url }; } @Post('jwt/kid-sql/login') @ApiCreatedResponse({ - type: LoginJwtResponse, + type: LoginJwtResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_KID_SQL_JWT, + description: SWAGGER_DESC_LOGIN_WITH_KID_SQL_JWT }) async loginWithKIDSqlJwt( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithKIDSqlJwt'); const profile = await this.loginBasic(req); @@ -271,8 +271,8 @@ export class AuthController { 'authorization', await this.authService.createToken( { user: profile.email }, - JwtProcessorType.SQL_KID, - ), + JwtProcessorType.SQL_KID + ) ); return profile; @@ -282,7 +282,7 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.SQL_KID) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -290,39 +290,39 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_KID_SQL_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_KID_SQL_JWT }) async validateWithKIDSqlJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @Post('jwt/weak-key/login') @ApiCreatedResponse({ - type: LoginJwtResponse, + type: LoginJwtResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_WEAK_KEY_JWT, + description: SWAGGER_DESC_LOGIN_WITH_WEAK_KEY_JWT }) async loginWithWeakKeyJwt( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithKIDSqlJwt'); const profile = await this.loginBasic(req); @@ -331,8 +331,8 @@ export class AuthController { 'authorization', await this.authService.createToken( { user: profile.email }, - JwtProcessorType.WEAK_KEY, - ), + JwtProcessorType.WEAK_KEY + ) ); return profile; @@ -342,10 +342,10 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.WEAK_KEY) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_WEAK_KEY_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_WEAK_KEY_JWT }) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -353,19 +353,19 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) async validateWithWeakKeyJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @Post('jwt/jku/login') @ApiCreatedResponse({ - type: LoginJwtResponse, + type: LoginJwtResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -373,16 +373,16 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_JKU_JWT, + description: SWAGGER_DESC_LOGIN_WITH_JKU_JWT }) async loginWithJKUJwt( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithJKUJwt'); const profile = await this.loginBasic(req); @@ -391,8 +391,8 @@ export class AuthController { 'authorization', await this.authService.createToken( { user: profile.email }, - JwtProcessorType.JKU, - ), + JwtProcessorType.JKU + ) ); return profile; @@ -402,10 +402,10 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.JKU) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_JKU_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_JKU_JWT }) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -413,36 +413,36 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) async validateWithJKUJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @Post('jwt/jwk/login') @ApiCreatedResponse({ - type: LoginJwtResponse, + type: LoginJwtResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_JWK_JWT, + description: SWAGGER_DESC_LOGIN_WITH_JWK_JWT }) async loginWithJWKJwt( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithJWKJwt'); const profile = await this.loginBasic(req); @@ -451,8 +451,8 @@ export class AuthController { 'authorization', await this.authService.createToken( { user: profile.email }, - JwtProcessorType.JWK, - ), + JwtProcessorType.JWK + ) ); return profile; @@ -462,10 +462,10 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.JWK) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_JWK_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_JWK_JWT }) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -473,36 +473,36 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) async validateWithJWKJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @Post('jwt/x5c/login') @ApiCreatedResponse({ - type: LoginJwtResponse, + type: LoginJwtResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_X5C_JWT, + description: SWAGGER_DESC_LOGIN_WITH_X5C_JWT }) async loginWithX5CJwt( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithX5CJwt'); const profile = await this.loginBasic(req); @@ -511,8 +511,8 @@ export class AuthController { 'authorization', await this.authService.createToken( { user: profile.email }, - JwtProcessorType.X5C, - ), + JwtProcessorType.X5C + ) ); return profile; @@ -522,10 +522,10 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.X5C) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_X5C_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_X5C_JWT }) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -533,36 +533,36 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) async validateWithX5CJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @Post('jwt/x5u/login') @ApiCreatedResponse({ - type: LoginJwtResponse, + type: LoginJwtResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_X5U_JWT, + description: SWAGGER_DESC_LOGIN_WITH_X5U_JWT }) async loginWithX5UJwt( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithX5UJwt'); const profile = await this.loginBasic(req); @@ -571,8 +571,8 @@ export class AuthController { 'Authorization', await this.authService.createToken( { user: profile.email }, - JwtProcessorType.X5U, - ), + JwtProcessorType.X5U + ) ); return profile; @@ -582,10 +582,10 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.X5U) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_X5U_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_X5U_JWT }) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -593,36 +593,36 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) async validateWithX5UJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @Post('jwt/hmac/login') @ApiCreatedResponse({ - type: LoginJwtResponse, + type: LoginJwtResponse }) @ApiUnauthorizedResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, + location: { type: 'string' } + } }, - description: 'invalid credentials', + description: 'invalid credentials' }) @ApiOperation({ - description: SWAGGER_DESC_LOGIN_WITH_HMAC_JWT, + description: SWAGGER_DESC_LOGIN_WITH_HMAC_JWT }) async loginWithHMACJwt( @Body() req: LoginRequest, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ): Promise { this.logger.debug('Call loginWithHMACJwt'); const profile = await this.loginBasic(req); @@ -631,8 +631,8 @@ export class AuthController { 'authorization', await this.authService.createToken( { user: profile.email }, - JwtProcessorType.HMAC, - ), + JwtProcessorType.HMAC + ) ); return profile; @@ -642,10 +642,10 @@ export class AuthController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.HMAC) @ApiOperation({ - description: SWAGGER_DESC_VALIDATE_WITH_HMAC_JWT, + description: SWAGGER_DESC_VALIDATE_WITH_HMAC_JWT }) @ApiOkResponse({ - type: JwtValidationResponse, + type: JwtValidationResponse }) @ApiUnauthorizedResponse({ description: 'invalid credentials', @@ -653,13 +653,13 @@ export class AuthController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) async validateWithHMACJwt(): Promise { return { - secret: 'this is our secret', + secret: 'this is our secret' }; } @@ -668,25 +668,25 @@ export class AuthController { const { token_type, access_token } = await this.keyCloakService.generateToken({ username: req.user, - password: req.password, + password: req.password }); return { email: req.user, ldapProfileLink: LdapQueryHandler.LDAP_SEARCH_QUERY(req.user), - token: `${token_type} ${access_token}`, + token: `${token_type} ${access_token}` }; } catch (err) { if (err.response.status === 401) { throw new UnauthorizedException({ error: 'Invalid credentials', - location: __filename, + location: __filename }); } throw new InternalServerErrorException({ error: err.message, - location: __filename, + location: __filename }); } } @@ -699,36 +699,36 @@ export class AuthController { } catch (err) { throw new InternalServerErrorException({ error: err.message, - location: __filename, + location: __filename }); } if (!user || !(await passwordMatches(req.password, user.password))) { throw new UnauthorizedException({ error: 'Invalid credentials', - location: __filename, + location: __filename }); } if (!user.isBasic) { throw new ForbiddenException({ error: 'Invalid authentication method for this user', - location: __filename, + location: __filename }); } const token = await this.authService.createToken( { user: user.email, - exp: 90 + Math.floor(Date.now() / 1000), + exp: 90 + Math.floor(Date.now() / 1000) }, - JwtProcessorType.RSA, + JwtProcessorType.RSA ); return { token, email: user.email, - ldapProfileLink: LdapQueryHandler.LDAP_SEARCH_QUERY(user.email), + ldapProfileLink: LdapQueryHandler.LDAP_SEARCH_QUERY(user.email) }; } } diff --git a/src/auth/auth.guard.ts b/src/auth/auth.guard.ts index d6eb3d48..1bd9577e 100644 --- a/src/auth/auth.guard.ts +++ b/src/auth/auth.guard.ts @@ -3,7 +3,7 @@ import { Injectable, Logger, UnauthorizedException, - ExecutionContext, + ExecutionContext } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { AuthService, JwtProcessorType } from './auth.service'; @@ -19,7 +19,7 @@ export class AuthGuard implements CanActivate { constructor( private readonly authService: AuthService, - private readonly reflector: Reflector, + private readonly reflector: Reflector ) {} async canActivate(context: ExecutionContext) { @@ -37,7 +37,7 @@ export class AuthGuard implements CanActivate { this.logger.debug(`Failed to validate token: ${err.message}`); throw new UnauthorizedException({ error: 'Unauthorized', - line: __filename, + line: __filename }); } } @@ -64,11 +64,11 @@ export class AuthGuard implements CanActivate { private async verifyToken( token: string, - context: ExecutionContext, + context: ExecutionContext ): Promise { const processorType = this.reflector.get( JwTypeMetadataField, - context.getHandler(), + context.getHandler() ); try { @@ -76,7 +76,7 @@ export class AuthGuard implements CanActivate { } catch { return !!(await this.authService.validateToken( token, - JwtProcessorType.BEARER, + JwtProcessorType.BEARER )); } } diff --git a/src/auth/auth.module.config.properties.ts b/src/auth/auth.module.config.properties.ts index 67a827d0..62e29adf 100644 --- a/src/auth/auth.module.config.properties.ts +++ b/src/auth/auth.module.config.properties.ts @@ -7,5 +7,5 @@ export enum AuthModuleConfigProperties { ENV_JWK_PUBLIC_KEY_LOCATION = 'JWK_PUBLIC_KEY_LOCATION', ENV_JWK_PUBLIC_JSON = 'JWK_PUBLIC_JSON', ENV_JKU_URL = 'JKU_URL', - ENV_X5U_URL = 'X5U_URL', + ENV_X5U_URL = 'X5U_URL' } diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index e7fb819e..a84e5f3f 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -11,10 +11,10 @@ import { KeyCloakModule } from '../keycloak/keycloak.module'; forwardRef(() => UsersModule), OrmModule, KeyCloakModule, - HttpClientModule, + HttpClientModule ], providers: [AuthService], controllers: [AuthController], - exports: [AuthService], + exports: [AuthService] }) export class AuthModule {} diff --git a/src/auth/auth.service.spec.ts b/src/auth/auth.service.spec.ts index 002d3b7f..77cd9856 100644 --- a/src/auth/auth.service.spec.ts +++ b/src/auth/auth.service.spec.ts @@ -7,8 +7,8 @@ import { AuthService } from './auth.service'; jest.mock('fs', () => ({ readFileSync: jest.fn((path: string) => - path.toLowerCase().includes('json') ? '{}' : 'mocked-key-content', - ), + path.toLowerCase().includes('json') ? '{}' : 'mocked-key-content' + ) })); jest.mock('@mikro-orm/core', () => ({ @@ -17,8 +17,8 @@ jest.mock('@mikro-orm/core', () => ({ find: jest.fn(), findOne: jest.fn(), persist: jest.fn(), - flush: jest.fn(), - })), + flush: jest.fn() + })) })); describe('AuthService', () => { @@ -31,23 +31,23 @@ describe('AuthService', () => { { provide: EntityManager, // eslint-disable-next-line @typescript-eslint/no-explicit-any - useFactory: () => new (EntityManager as any)(), + useFactory: () => new (EntityManager as any)() }, { provide: KeyCloakService, - useValue: {}, + useValue: {} }, { provide: HttpClientService, - useValue: {}, + useValue: {} }, { provide: ConfigService, useValue: { - get: (key: string) => key, - }, - }, - ], + get: (key: string) => key + } + } + ] }).compile(); service = module.get(AuthService); diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 9ac7773f..e7459f1a 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -27,7 +27,7 @@ export enum JwtProcessorType { JWK, BEARER, HMAC, - RSA_SIGNATURE, + RSA_SIGNATURE } @Injectable() @@ -38,86 +38,86 @@ export class AuthService { private readonly configService: ConfigService, private readonly em: EntityManager, private readonly httpClient: HttpClientService, - private readonly keyCloakService: KeyCloakService, + private readonly keyCloakService: KeyCloakService ) { const privateKey = fs.readFileSync( this.configService.get( - AuthModuleConfigProperties.ENV_JWT_PRIVATE_KEY_LOCATION, + AuthModuleConfigProperties.ENV_JWT_PRIVATE_KEY_LOCATION ), - 'utf8', + 'utf8' ); const publicKey = fs.readFileSync( this.configService.get( - AuthModuleConfigProperties.ENV_JWT_PUBLIC_KEY_LOCATION, + AuthModuleConfigProperties.ENV_JWT_PUBLIC_KEY_LOCATION ), - 'utf8', + 'utf8' ); const jwkPrivateKey = fs.readFileSync( this.configService.get( - AuthModuleConfigProperties.ENV_JWK_PRIVATE_KEY_LOCATION, + AuthModuleConfigProperties.ENV_JWK_PRIVATE_KEY_LOCATION ), - 'utf8', + 'utf8' ); const jwkPublicJson = JSON.parse( fs.readFileSync( this.configService.get( - AuthModuleConfigProperties.ENV_JWK_PUBLIC_JSON, + AuthModuleConfigProperties.ENV_JWK_PUBLIC_JSON ), - 'utf8', - ), + 'utf8' + ) ); const jkuUrl = this.configService.get( - AuthModuleConfigProperties.ENV_JKU_URL, + AuthModuleConfigProperties.ENV_JKU_URL ); const x5uUrl = this.configService.get( - AuthModuleConfigProperties.ENV_X5U_URL, + AuthModuleConfigProperties.ENV_X5U_URL ); const jwtSecretKey = configService.get( - AuthModuleConfigProperties.ENV_JWT_SECRET_KEY, + AuthModuleConfigProperties.ENV_JWT_SECRET_KEY ); this.processors = new Map(); this.processors.set( JwtProcessorType.RSA, - new JwtTokenWithRSAKeysProcessor(publicKey, privateKey), + new JwtTokenWithRSAKeysProcessor(publicKey, privateKey) ); this.processors.set( JwtProcessorType.SQL_KID, - new JwtTokenWithSqlKIDProcessor(this.em, jwtSecretKey), + new JwtTokenWithSqlKIDProcessor(this.em, jwtSecretKey) ); this.processors.set( JwtProcessorType.WEAK_KEY, - new JwtTokenWithWeakKeyProcessor(jwtSecretKey), + new JwtTokenWithWeakKeyProcessor(jwtSecretKey) ); this.processors.set( JwtProcessorType.JKU, - new JwtTokenWithJKUProcessor(jwkPrivateKey, this.httpClient, jkuUrl), + new JwtTokenWithJKUProcessor(jwkPrivateKey, this.httpClient, jkuUrl) ); this.processors.set( JwtProcessorType.JWK, - new JwtTokenWithJWKProcessor(jwkPrivateKey, jwkPublicJson), + new JwtTokenWithJWKProcessor(jwkPrivateKey, jwkPublicJson) ); this.processors.set( JwtProcessorType.X5C, - new JwtTokenWithX5CKeyProcessor(jwkPrivateKey), + new JwtTokenWithX5CKeyProcessor(jwkPrivateKey) ); this.processors.set( JwtProcessorType.X5U, - new JwtTokenWithX5UKeyProcessor(jwkPrivateKey, this.httpClient, x5uUrl), + new JwtTokenWithX5UKeyProcessor(jwkPrivateKey, this.httpClient, x5uUrl) ); this.processors.set( JwtProcessorType.BEARER, - new JwtBearerTokenProcessor(jwtSecretKey, this.keyCloakService), + new JwtBearerTokenProcessor(jwtSecretKey, this.keyCloakService) ); this.processors.set( JwtProcessorType.HMAC, - new JwtTokenWithHMACKeysProcessor(publicKey, privateKey), + new JwtTokenWithHMACKeysProcessor(publicKey, privateKey) ); this.processors.set( JwtProcessorType.RSA_SIGNATURE, - new JwtTokenWithRSASignatureKeysProcessor(publicKey, privateKey), + new JwtTokenWithRSASignatureKeysProcessor(publicKey, privateKey) ); } diff --git a/src/auth/credentials.utils.ts b/src/auth/credentials.utils.ts index 7b6775de..4d50e45e 100644 --- a/src/auth/credentials.utils.ts +++ b/src/auth/credentials.utils.ts @@ -7,5 +7,5 @@ export const hashPassword = (password: string): Promise => export const passwordMatches = ( password: string, - hash: string, + hash: string ): Promise => compare(password, hash); diff --git a/src/auth/csrf.guard.ts b/src/auth/csrf.guard.ts index d925d486..cb83e648 100644 --- a/src/auth/csrf.guard.ts +++ b/src/auth/csrf.guard.ts @@ -3,7 +3,7 @@ import { CanActivate, UnauthorizedException, ExecutionContext, - Logger, + Logger } from '@nestjs/common'; import { createHash } from 'crypto'; import { FastifyRequest } from 'fastify'; @@ -49,7 +49,7 @@ export class CsrfGuard implements CanActivate { private throwError() { throw new UnauthorizedException({ error: 'Invalid credentials', - location: __filename, + location: __filename }); } } diff --git a/src/auth/jwt/jwt.token.bearer.processor.ts b/src/auth/jwt/jwt.token.bearer.processor.ts index f2524296..92bdd130 100644 --- a/src/auth/jwt/jwt.token.bearer.processor.ts +++ b/src/auth/jwt/jwt.token.bearer.processor.ts @@ -7,7 +7,7 @@ import { KeyCloakService } from '../../keycloak/keycloak.service'; export class JwtBearerTokenProcessor extends JwtTokenProcessor { constructor( private readonly key: string, - private readonly keyCloakService: KeyCloakService, + private readonly keyCloakService: KeyCloakService ) { super(new Logger(JwtBearerTokenProcessor.name)); } @@ -21,7 +21,7 @@ export class JwtBearerTokenProcessor extends JwtTokenProcessor { if (!header.kid) { this.log.debug( - `Invalid JWT token. Expected a known KID but found ${header.kid}.`, + `Invalid JWT token. Expected a known KID but found ${header.kid}.` ); throw new Error('Authorization header contains an invalid JWT token.'); } @@ -48,7 +48,7 @@ export class JwtBearerTokenProcessor extends JwtTokenProcessor { } catch (e) { if (e.statusCode === 401) { throw new Error( - `JWT token is expired or user has globally signed out, disabled or been deleted.`, + `JWT token is expired or user has globally signed out, disabled or been deleted.` ); } this.log.debug(`Failed to introspect JWT token. err: ${e.message}`); @@ -58,7 +58,7 @@ export class JwtBearerTokenProcessor extends JwtTokenProcessor { private async decodeAndVerifyToken( token: string, - kid: string, + kid: string ): Promise { try { return await this.keyCloakService.verifyToken(token, kid); @@ -66,7 +66,7 @@ export class JwtBearerTokenProcessor extends JwtTokenProcessor { this.log.debug(`Invalid JWT token. jwt.verify() failed: ${e.message}.`); if (e instanceof TokenExpiredError) { throw new Error( - `Authorization header contains a JWT token that expired at ${e.expiredAt.toISOString()}.`, + `Authorization header contains a JWT token that expired at ${e.expiredAt.toISOString()}.` ); } throw new Error('Authorization header contains an invalid JWT token.'); diff --git a/src/auth/jwt/jwt.token.processor.ts b/src/auth/jwt/jwt.token.processor.ts index d69f129f..8632b0c0 100644 --- a/src/auth/jwt/jwt.token.processor.ts +++ b/src/auth/jwt/jwt.token.processor.ts @@ -36,7 +36,7 @@ export abstract class JwtTokenProcessor { !chainText || (idx = Math.max( chainText.indexOf(JwtTokenProcessor.END_CERTIFICATE_MARK), - chainText.indexOf(JwtTokenProcessor.END_PUBLIC_KEY_MARK), + chainText.indexOf(JwtTokenProcessor.END_PUBLIC_KEY_MARK) )) === -1 ) { throw new Error('Invalid certificate'); @@ -44,7 +44,7 @@ export abstract class JwtTokenProcessor { const key = chainText.slice( 0, - idx + JwtTokenProcessor.END_CERTIFICATE_MARK.length, + idx + JwtTokenProcessor.END_CERTIFICATE_MARK.length ); this.log.debug(`Extracted key\n${key}`); return key; diff --git a/src/auth/jwt/jwt.token.with.hmac.keys.processor.ts b/src/auth/jwt/jwt.token.with.hmac.keys.processor.ts index 245ea7aa..ddbe0784 100644 --- a/src/auth/jwt/jwt.token.with.hmac.keys.processor.ts +++ b/src/auth/jwt/jwt.token.with.hmac.keys.processor.ts @@ -5,7 +5,7 @@ import { encode, decode } from 'jwt-simple'; export class JwtTokenWithHMACKeysProcessor extends JwtTokenProcessor { constructor( private publicKey: string, - private privateKey: string, + private privateKey: string ) { super(new Logger(JwtTokenWithHMACKeysProcessor.name)); } diff --git a/src/auth/jwt/jwt.token.with.jku.processor.ts b/src/auth/jwt/jwt.token.with.jku.processor.ts index c98f0b14..b74ed325 100644 --- a/src/auth/jwt/jwt.token.with.jku.processor.ts +++ b/src/auth/jwt/jwt.token.with.jku.processor.ts @@ -7,7 +7,7 @@ export class JwtTokenWithJKUProcessor extends JwtTokenProcessor { constructor( private key: string, private httpClient: HttpClientService, - private jkuUrl: string, + private jkuUrl: string ) { super(new Logger(JwtTokenWithJKUProcessor.name)); } @@ -34,7 +34,7 @@ export class JwtTokenWithJKUProcessor extends JwtTokenProcessor { .setProtectedHeader({ typ: 'JWT', alg: 'RS256', - jku: this.jkuUrl, + jku: this.jkuUrl }) .sign(pkcs8); } diff --git a/src/auth/jwt/jwt.token.with.jwk.processor.ts b/src/auth/jwt/jwt.token.with.jwk.processor.ts index 3d15a2ab..6570df71 100644 --- a/src/auth/jwt/jwt.token.with.jwk.processor.ts +++ b/src/auth/jwt/jwt.token.with.jwk.processor.ts @@ -5,7 +5,7 @@ import { JwtTokenProcessor as JwtTokenProcessor } from './jwt.token.processor'; export class JwtTokenWithJWKProcessor extends JwtTokenProcessor { constructor( private key: string, - private jwk: jose.JWK, + private jwk: jose.JWK ) { super(new Logger(JwtTokenWithJWKProcessor.name)); } @@ -38,7 +38,7 @@ export class JwtTokenWithJWKProcessor extends JwtTokenProcessor { .setProtectedHeader({ typ: 'JWT', alg: 'RS256', - jwk: this.jwk, + jwk: this.jwk }) .sign(pkcs8); } diff --git a/src/auth/jwt/jwt.token.with.rsa.keys.processor.ts b/src/auth/jwt/jwt.token.with.rsa.keys.processor.ts index 077d258f..5ee59ef4 100644 --- a/src/auth/jwt/jwt.token.with.rsa.keys.processor.ts +++ b/src/auth/jwt/jwt.token.with.rsa.keys.processor.ts @@ -5,7 +5,7 @@ import { JwtTokenProcessor as JwtTokenProcessor } from './jwt.token.processor'; export class JwtTokenWithRSAKeysProcessor extends JwtTokenProcessor { constructor( private publicKey: string, - private privateKey: string, + private privateKey: string ) { super(new Logger(JwtTokenWithRSAKeysProcessor.name)); } diff --git a/src/auth/jwt/jwt.token.with.rsa.signature.keys.processor.ts b/src/auth/jwt/jwt.token.with.rsa.signature.keys.processor.ts index b8f86fe7..62534482 100644 --- a/src/auth/jwt/jwt.token.with.rsa.signature.keys.processor.ts +++ b/src/auth/jwt/jwt.token.with.rsa.signature.keys.processor.ts @@ -5,7 +5,7 @@ import { JwtTokenProcessor as JwtTokenProcessor } from './jwt.token.processor'; export class JwtTokenWithRSASignatureKeysProcessor extends JwtTokenProcessor { constructor( private publicKey: string, - private privateKey: string, + private privateKey: string ) { super(new Logger(JwtTokenWithRSASignatureKeysProcessor.name)); } diff --git a/src/auth/jwt/jwt.token.with.sql.kid.processor.ts b/src/auth/jwt/jwt.token.with.sql.kid.processor.ts index e6d56b0f..d039a59d 100644 --- a/src/auth/jwt/jwt.token.with.sql.kid.processor.ts +++ b/src/auth/jwt/jwt.token.with.sql.kid.processor.ts @@ -11,7 +11,7 @@ export class JwtTokenWithSqlKIDProcessor extends JwtTokenProcessor { constructor( private readonly em: EntityManager, - private key: string, + private key: string ) { super(new Logger(JwtTokenWithSqlKIDProcessor.name)); } @@ -23,7 +23,7 @@ export class JwtTokenWithSqlKIDProcessor extends JwtTokenProcessor { const query = JwtTokenWithSqlKIDProcessor.KID_FETCH_QUERY( this.key, - header.kid, + header.kid ); this.log.debug(`Executing key fetching query: ${query}`); const keyRow: { key: string } = await this.em @@ -39,10 +39,10 @@ export class JwtTokenWithSqlKIDProcessor extends JwtTokenProcessor { const header: JwtHeader = { alg: 'HS256', kid: `${JwtTokenWithSqlKIDProcessor.KID}`, - typ: 'JWT', + typ: 'JWT' }; const token = encode(payload, this.key, 'HS256', { - header, + header }); return token; } diff --git a/src/auth/jwt/jwt.token.with.x5c.key.processor.ts b/src/auth/jwt/jwt.token.with.x5c.key.processor.ts index 38b21dd0..13cdfc9e 100644 --- a/src/auth/jwt/jwt.token.with.x5c.key.processor.ts +++ b/src/auth/jwt/jwt.token.with.x5c.key.processor.ts @@ -24,7 +24,7 @@ export class JwtTokenWithX5CKeyProcessor extends JwtTokenProcessor { .setProtectedHeader({ typ: 'JWT', alg: 'RS256', - x5c: [this.key], + x5c: [this.key] }) .sign(pkcs8); } diff --git a/src/auth/jwt/jwt.token.with.x5u.key.processor.ts b/src/auth/jwt/jwt.token.with.x5u.key.processor.ts index 30c6568d..c6509dd1 100644 --- a/src/auth/jwt/jwt.token.with.x5u.key.processor.ts +++ b/src/auth/jwt/jwt.token.with.x5u.key.processor.ts @@ -6,7 +6,7 @@ export class JwtTokenWithX5UKeyProcessor extends JwtTokenProcessor { constructor( private key: string, private httpClient: HttpClientService, - private x5uUrl: string, + private x5uUrl: string ) { super(new Logger(JwtTokenWithX5UKeyProcessor.name)); } @@ -31,7 +31,7 @@ export class JwtTokenWithX5UKeyProcessor extends JwtTokenProcessor { .setProtectedHeader({ typ: 'JWT', alg: 'RS256', - x5u: this.x5uUrl, + x5u: this.x5uUrl }) .sign(pkcs8); } diff --git a/src/chat/api/ChatMessage.ts b/src/chat/api/ChatMessage.ts index 5d5159e4..fc87c271 100644 --- a/src/chat/api/ChatMessage.ts +++ b/src/chat/api/ChatMessage.ts @@ -4,12 +4,12 @@ export class ChatMessage { @ApiProperty({ description: 'The role of the messages author. Choice between: system, user, or assistant', - enum: ['user', 'assistant', 'system'], + enum: ['user', 'assistant', 'system'] }) role: 'user' | 'assistant' | 'system'; @ApiProperty({ - description: 'The contents of the message', + description: 'The contents of the message' }) content: string; } diff --git a/src/chat/chat.controller.ts b/src/chat/chat.controller.ts index a2e9c538..9e19bda7 100644 --- a/src/chat/chat.controller.ts +++ b/src/chat/chat.controller.ts @@ -3,7 +3,7 @@ import { Controller, HttpException, HttpStatus, - Post, + Post } from '@nestjs/common'; import { ApiBody, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; import { ChatService } from './chat.service'; @@ -19,11 +19,11 @@ export class ChatController { @ApiOperation({ description: API_DESC_CHAT_QUESTION }) @ApiBody({ description: 'A list of messages comprising the conversation so far', - type: [ChatMessage], + type: [ChatMessage] }) @ApiOkResponse({ description: 'Chatbot answer', - type: String, + type: String }) async query(@Body() messages: ChatMessage[]): Promise { try { @@ -31,7 +31,7 @@ export class ChatController { } catch (err) { throw new HttpException( `Chat API response error: ${err}`, - HttpStatus.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR ); } } diff --git a/src/chat/chat.module.ts b/src/chat/chat.module.ts index 442b6bbc..09757130 100644 --- a/src/chat/chat.module.ts +++ b/src/chat/chat.module.ts @@ -7,6 +7,6 @@ import { HttpClientModule } from '../httpclient/httpclient.module'; imports: [HttpClientModule], controllers: [ChatController], providers: [ChatService], - exports: [], + exports: [] }) export class ChatModule {} diff --git a/src/chat/chat.service.ts b/src/chat/chat.service.ts index 998d967c..9998b620 100644 --- a/src/chat/chat.service.ts +++ b/src/chat/chat.service.ts @@ -33,7 +33,7 @@ export class ChatService { !process.env.CHAT_API_TOKEN ) { throw new Error( - 'Chat API environment variables are missing. CHAT_API_URL, CHAT_API_MODEL, CHAT_API_TOKEN are mandatory.', + 'Chat API environment variables are missing. CHAT_API_URL, CHAT_API_MODEL, CHAT_API_TOKEN are mandatory.' ); } @@ -42,7 +42,7 @@ export class ChatService { messages, max_tokens: +process.env.CHAT_API_MAX_TOKENS || DEFAULT_CHAT_API_MAX_TOKENS, - stream: false, + stream: false }; const res = await this.httpClient.post( @@ -51,9 +51,9 @@ export class ChatService { { headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${process.env.CHAT_API_TOKEN}`, - }, - }, + Authorization: `Bearer ${process.env.CHAT_API_TOKEN}` + } + } ); return res?.choices?.[0]?.message?.content; diff --git a/src/components/any-files.interceptor.ts b/src/components/any-files.interceptor.ts index 4c700b0f..be0817e3 100644 --- a/src/components/any-files.interceptor.ts +++ b/src/components/any-files.interceptor.ts @@ -3,7 +3,7 @@ import { CallHandler, ExecutionContext, Injectable, - NestInterceptor, + NestInterceptor } from '@nestjs/common'; import { Observable } from 'rxjs'; import { FastifyReply, FastifyRequest } from 'fastify'; @@ -12,7 +12,7 @@ import { FastifyReply, FastifyRequest } from 'fastify'; export class AnyFilesInterceptor implements NestInterceptor { public async intercept( context: ExecutionContext, - next: CallHandler, + next: CallHandler ): Promise> { const req = context.switchToHttp().getRequest() as FastifyRequest; const res = context.switchToHttp().getResponse() as FastifyReply; @@ -21,8 +21,8 @@ export class AnyFilesInterceptor implements NestInterceptor { res.send( new BadRequestException({ error: 'Request is not multipart', - location: __filename, - }), + location: __filename + }) ); return; } diff --git a/src/components/global-exception.filter.ts b/src/components/global-exception.filter.ts index 67383644..d6c1041e 100644 --- a/src/components/global-exception.filter.ts +++ b/src/components/global-exception.filter.ts @@ -2,7 +2,7 @@ import { ArgumentsHost, Catch, HttpException, - InternalServerErrorException, + InternalServerErrorException } from '@nestjs/common'; import { BaseExceptionFilter } from '@nestjs/core'; import { GqlContextType } from '@nestjs/graphql'; @@ -22,7 +22,7 @@ export class GlobalExceptionFilter extends BaseExceptionFilter { const unprocessableException = new InternalServerErrorException( { error: (exception as Error).message, location: __filename }, - 'An internal error has occurred, and the API was unable to service your request.', + 'An internal error has occurred, and the API was unable to service your request.' ); if (gql) { @@ -36,7 +36,7 @@ export class GlobalExceptionFilter extends BaseExceptionFilter { return applicationRef.reply( host.getArgByIndex(1), unprocessableException.getResponse(), - unprocessableException.getStatus(), + unprocessableException.getStatus() ); } } diff --git a/src/components/headers.configurator.interceptor.ts b/src/components/headers.configurator.interceptor.ts index 00cb78ce..2a368c18 100644 --- a/src/components/headers.configurator.interceptor.ts +++ b/src/components/headers.configurator.interceptor.ts @@ -3,7 +3,7 @@ import { ExecutionContext, Injectable, Logger, - NestInterceptor, + NestInterceptor } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @@ -36,7 +36,7 @@ export class HeadersConfiguratorInterceptor implements NestInterceptor { const cookie = cookies .reverse() .find((str) => - str.startsWith(HeadersConfiguratorInterceptor.COUNTER_COOKIE_NAME), + str.startsWith(HeadersConfiguratorInterceptor.COUNTER_COOKIE_NAME) ); this.logger.log(`Cookie header: ${cookie}`); @@ -54,7 +54,7 @@ export class HeadersConfiguratorInterceptor implements NestInterceptor { tap(() => { const res = this.getResponse(context); res.setCookie('bc-calls-counter', Date.now().toString(), { - secure: false, + secure: false }); if ( !req.query[HeadersConfiguratorInterceptor.NO_SEC_HEADERS_QUERY_PARAM] @@ -62,15 +62,15 @@ export class HeadersConfiguratorInterceptor implements NestInterceptor { res.header(HeadersConfiguratorInterceptor.XSS_PROTECTION_HEADER, '0'); res.header( HeadersConfiguratorInterceptor.STRICT_TRANSPORT_SECURITY_HEADER, - 'max-age=0', + 'max-age=0' ); res.header(HeadersConfiguratorInterceptor.CONTENT_TYPE_OPTIONS, '1'); res.header( HeadersConfiguratorInterceptor.CONTENT_SECURITY_POLICY, - `default-src * 'unsafe-inline' 'unsafe-eval'`, + `default-src * 'unsafe-inline' 'unsafe-eval'` ); } - }), + }) ); } diff --git a/src/email/email.controller.ts b/src/email/email.controller.ts index 6a55e94b..a3fbc5dd 100644 --- a/src/email/email.controller.ts +++ b/src/email/email.controller.ts @@ -7,14 +7,14 @@ import { HttpStatus, Logger, Query, - Res, + Res } from '@nestjs/common'; import { ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger'; import { EmailService } from './email.service'; import { SWAGGER_DESC_DELTE_EMAILS, SWAGGER_DESC_GET_EMAILS, - SWAGGER_DESC_SEND_EMAIL, + SWAGGER_DESC_SEND_EMAIL } from './email.controller.swagger.desc'; import splitUriIntoParamsPPVulnerable from '../utils/url'; @@ -31,25 +31,25 @@ export class EmailController { @ApiQuery({ name: 'name', example: 'Bob Dylan', - required: true, + required: true }) @ApiQuery({ name: 'to', example: 'username@email.com', - required: true, + required: true }) @ApiQuery({ name: 'subject', example: 'Help Request', - required: true, + required: true }) @ApiQuery({ name: 'content', example: 'I would like to request help regarding..', - required: true, + required: true }) @ApiOperation({ - description: SWAGGER_DESC_SEND_EMAIL, + description: SWAGGER_DESC_SEND_EMAIL }) @Header('Content-Type', 'application/json') async sendSupportEmail( @@ -58,14 +58,14 @@ export class EmailController { @Query('subject') subject: string, @Query('content') content: string, @Query() query, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { this.logger.log('Sending a support Email'); // This is defined here intentionally so we don't override responseJson.status after the prototype pollution has occurred const responseJson = { message: {}, - status: HttpStatus.OK, + status: HttpStatus.OK }; // "Accidentally" forgot this here while coding... Oops. @@ -95,7 +95,7 @@ export class EmailController { this.BC_EMAIL_ADDRESS, to, mailSubject, - mailBody, + mailBody ); if (didSucceed) { @@ -111,12 +111,12 @@ export class EmailController { @Get('/getEmails') @ApiOperation({ - description: SWAGGER_DESC_GET_EMAILS, + description: SWAGGER_DESC_GET_EMAILS }) @ApiQuery({ name: 'withSource', example: 'true', - required: true, + required: true }) async getEmails(@Query('withSource') withSourceStr: string) { const withSource = withSourceStr === 'true'; @@ -127,7 +127,7 @@ export class EmailController { @Delete('/deleteEmails') @ApiOperation({ - description: SWAGGER_DESC_DELTE_EMAILS, + description: SWAGGER_DESC_DELTE_EMAILS }) async deleteEmails() { this.logger.log('Deleting Emails'); diff --git a/src/email/email.module.ts b/src/email/email.module.ts index e0ed64b5..9b7cc3a9 100644 --- a/src/email/email.module.ts +++ b/src/email/email.module.ts @@ -5,6 +5,6 @@ import { EmailService } from './email.service'; @Module({ imports: [], controllers: [EmailController], - providers: [EmailService], + providers: [EmailService] }) export class EmailModule {} diff --git a/src/email/email.service.ts b/src/email/email.service.ts index 5986de0f..0fd76c05 100644 --- a/src/email/email.service.ts +++ b/src/email/email.service.ts @@ -12,8 +12,8 @@ export class EmailService { secure: false, auth: { user: 'mailcatcher', - pass: 'mailcatcher', - }, + pass: 'mailcatcher' + } }; private readonly transporter = createTransport(this.smtpServerDetails); @@ -25,11 +25,11 @@ export class EmailService { from: string, to: string, subject: string, - body: string, + body: string ): Promise { this.logger.debug(`Sending mail from "${from}" to "${to}"`); this.logger.debug( - `Mail subject is (trimmed): "${subject.substring(0, 64)}"`, + `Mail subject is (trimmed): "${subject.substring(0, 64)}"` ); this.logger.debug(`Mail body is (trimmed): "${body.substring(0, 64)}"`); @@ -37,7 +37,7 @@ export class EmailService { from, to, subject, - body, + body ); const response = await this.transporter.sendMail(mailOptions); @@ -55,7 +55,7 @@ export class EmailService { from: string, to: string, subject: string, - body: string, + body: string ) { to = to.replace('\n', '%0A'); this.logger.debug(`Creating vulnerable mailOptions. "to" param is: ${to}`); @@ -88,7 +88,7 @@ export class EmailService { } this.logger.debug( - `parsedFrom: ${parsedFrom} | parsedTo: ${parsedTo} | parsedCc: ${parsedCc} | parsedBcc: ${parsedBcc}`, + `parsedFrom: ${parsedFrom} | parsedTo: ${parsedTo} | parsedCc: ${parsedCc} | parsedBcc: ${parsedBcc}` ); // Build final raw email @@ -116,9 +116,9 @@ export class EmailService { from: parsedFrom, to: parsedTo, cc: parsedCc ? [parsedCc] : [], - bcc: parsedCc ? [parsedCc] : [], + bcc: parsedCc ? [parsedCc] : [] }, - raw: rawContent, + raw: rawContent }; return mailOptions; @@ -132,7 +132,7 @@ export class EmailService { .then((res) => res.status == HttpStatus.OK ? res.data - : { error: 'Failed to get emails' }, + : { error: 'Failed to get emails' } ); if (withSource) { @@ -153,12 +153,12 @@ export class EmailService { .then((res) => res.status == HttpStatus.OK ? res.data - : { error: 'Failed to get emails' }, + : { error: 'Failed to get emails' } ) .catch((err) => this.logger.debug( - `Failed to fetch email source with id ${emailId} via "${sourceUrl}". Error: ${err}`, - ), + `Failed to fetch email source with id ${emailId} via "${sourceUrl}". Error: ${err}` + ) ); } @@ -167,7 +167,7 @@ export class EmailService { return await axios .get(this.MAIL_CATCHER_MESSAGES_URL, { - method: 'DELETE', + method: 'DELETE' }) .then((res) => res.status == HttpStatus.OK); } diff --git a/src/file/cloud.providers.metadata.ts b/src/file/cloud.providers.metadata.ts index 6fd594fd..8b7d9146 100644 --- a/src/file/cloud.providers.metadata.ts +++ b/src/file/cloud.providers.metadata.ts @@ -31,7 +31,7 @@ export class CloudProvidersMetaData { guest-attributes maintenance-event network-interfaces/ - `.trim(), + `.trim() ); this.providers.set( CloudProvidersMetaData.DIGITAL_OCEAN, @@ -86,7 +86,7 @@ export class CloudProvidersMetaData { "dhcp_enabled": true } } - `.trim(), + `.trim() ); this.providers.set( CloudProvidersMetaData.AZURE, @@ -209,7 +209,7 @@ export class CloudProvidersMetaData { }] } } - `.trim(), + `.trim() ); this.providers.set( CloudProvidersMetaData.AWS, @@ -238,7 +238,7 @@ export class CloudProvidersMetaData { reservation-id security-groups services/ - `.trim(), + `.trim() ); this.providers.set( CloudProvidersMetaData.DIGITAL_OCEAN, @@ -254,7 +254,7 @@ export class CloudProvidersMetaData { floating_ip/ tags/ features/ - `.trim(), + `.trim() ); } @@ -270,7 +270,7 @@ export class CloudProvidersMetaData { } else { const { data } = await axios(providerUrl, { timeout: 5000, - responseType: 'text', + responseType: 'text' }); return data; } diff --git a/src/file/file.controller.spec.ts b/src/file/file.controller.spec.ts index 1c6176f2..1b5a6151 100644 --- a/src/file/file.controller.spec.ts +++ b/src/file/file.controller.spec.ts @@ -11,9 +11,9 @@ describe('FileController', () => { providers: [ { provide: FileService, - useValue: {}, - }, - ], + useValue: {} + } + ] }).compile(); controller = module.get(FileController); diff --git a/src/file/file.controller.ts b/src/file/file.controller.ts index 388c8a54..f16058c0 100644 --- a/src/file/file.controller.ts +++ b/src/file/file.controller.ts @@ -8,7 +8,7 @@ import { Logger, Put, Query, - Res, + Res } from '@nestjs/common'; import { ApiHeader, @@ -17,7 +17,7 @@ import { ApiOkResponse, ApiOperation, ApiQuery, - ApiTags, + ApiTags } from '@nestjs/swagger'; import { W_OK } from 'constants'; import * as fs from 'fs'; @@ -29,7 +29,7 @@ import { SWAGGER_DESC_DELETE_FILE, SWAGGER_DESC_READ_FILE, SWAGGER_DESC_READ_FILE_ON_SERVER, - SWAGGER_DESC_SAVE_RAW_CONTENT, + SWAGGER_DESC_SAVE_RAW_CONTENT } from './file.controller.swagger.desc'; import { CloudProvidersMetaData } from './cloud.providers.metadata'; @@ -62,29 +62,29 @@ export class FileController { @ApiQuery({ name: 'path', example: 'config/products/crystals/amethyst.jpg', - required: true, + required: true }) @ApiQuery({ name: 'type', example: 'image/jpg', required: true }) @ApiHeader({ name: 'accept', example: 'image/jpg', required: true }) @ApiOkResponse({ - description: 'File read successfully', + description: 'File read successfully' }) @ApiInternalServerErrorResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_READ_FILE, + description: SWAGGER_DESC_READ_FILE }) async loadFile( @Query('path') path: string, @Query('type') contentType: string, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { const file: Stream = await this.fileService.getFile(path); const type = this.getContentType(contentType); @@ -97,33 +97,33 @@ export class FileController { @ApiQuery({ name: 'path', example: 'config/products/crystals/amethyst.jpg', - required: true, + required: true }) @ApiQuery({ name: 'type', example: 'image/jpg', required: true }) @ApiHeader({ name: 'accept', example: 'image/jpg', required: true }) @ApiOkResponse({ - description: 'File read successfully', + description: 'File read successfully' }) @ApiInternalServerErrorResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_READ_FILE, + description: SWAGGER_DESC_READ_FILE }) async loadGoogleFile( @Query('path') path: string, @Query('type') contentType: string, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { const file: Stream = await this.loadCPFile( CloudProvidersMetaData.GOOGLE, - path, + path ); const type = this.getContentType(contentType); res.type(type); @@ -135,33 +135,33 @@ export class FileController { @ApiQuery({ name: 'path', example: 'config/products/crystals/amethyst.jpg', - required: true, + required: true }) @ApiQuery({ name: 'type', example: 'image/jpg', required: true }) @ApiHeader({ name: 'accept', example: 'image/jpg', required: true }) @ApiOkResponse({ - description: 'File read successfully', + description: 'File read successfully' }) @ApiInternalServerErrorResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_READ_FILE, + description: SWAGGER_DESC_READ_FILE }) async loadAwsFile( @Query('path') path: string, @Query('type') contentType: string, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { const file: Stream = await this.loadCPFile( CloudProvidersMetaData.AWS, - path, + path ); const type = this.getContentType(contentType); res.type(type); @@ -173,33 +173,33 @@ export class FileController { @ApiQuery({ name: 'path', example: 'config/products/crystals/amethyst.jpg', - required: true, + required: true }) @ApiQuery({ name: 'type', example: 'image/jpg', required: true }) @ApiHeader({ name: 'accept', example: 'image/jpg', required: true }) @ApiOkResponse({ - description: 'File read successfully', + description: 'File read successfully' }) @ApiInternalServerErrorResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_READ_FILE, + description: SWAGGER_DESC_READ_FILE }) async loadAzureFile( @Query('path') path: string, @Query('type') contentType: string, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { const file: Stream = await this.loadCPFile( CloudProvidersMetaData.AZURE, - path, + path ); const type = this.getContentType(contentType); res.type(type); @@ -211,33 +211,33 @@ export class FileController { @ApiQuery({ name: 'path', example: 'config/products/crystals/amethyst.jpg', - required: true, + required: true }) @ApiQuery({ name: 'type', example: 'image/jpg', required: true }) @ApiHeader({ name: 'accept', example: 'image/jpg', required: true }) @ApiOkResponse({ - description: 'File read successfully', + description: 'File read successfully' }) @ApiInternalServerErrorResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOperation({ - description: SWAGGER_DESC_READ_FILE, + description: SWAGGER_DESC_READ_FILE }) async loadDigitalOceanFile( @Query('path') path: string, @Query('type') contentType: string, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { const file: Stream = await this.loadCPFile( CloudProvidersMetaData.DIGITAL_OCEAN, - path, + path ); const type = this.getContentType(contentType); res.type(type); @@ -249,22 +249,22 @@ export class FileController { @ApiQuery({ name: 'path', example: 'config/products/crystals/some_file.jpg', - required: true, + required: true }) @ApiOperation({ - description: SWAGGER_DESC_DELETE_FILE, + description: SWAGGER_DESC_DELETE_FILE }) @ApiInternalServerErrorResponse({ schema: { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) @ApiOkResponse({ - description: 'File deleted successfully', + description: 'File deleted successfully' }) async deleteFile(@Query('path') path: string): Promise { await this.fileService.deleteFile(path); @@ -274,15 +274,15 @@ export class FileController { @ApiQuery({ name: 'path', example: 'some/path/to/file.png', - required: true, + required: true }) @ApiOperation({ - description: SWAGGER_DESC_SAVE_RAW_CONTENT, + description: SWAGGER_DESC_SAVE_RAW_CONTENT }) @ApiOkResponse() async uploadFile( @Query('path') file: string, - @Body() raw: string, + @Body() raw: string ): Promise { try { if (typeof raw === 'string' || Buffer.isBuffer(raw)) { @@ -300,20 +300,20 @@ export class FileController { @ApiQuery({ name: 'path', example: 'config/products/crystals/amethyst.jpg', - required: true, + required: true }) @ApiOperation({ - description: SWAGGER_DESC_READ_FILE_ON_SERVER, + description: SWAGGER_DESC_READ_FILE_ON_SERVER }) @ApiNotFoundResponse({ - description: 'File not found', + description: 'File not found' }) @ApiOkResponse({ - description: 'Returns requested file', + description: 'Returns requested file' }) async readFile( @Query('path') file: string, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { try { const stream = await this.fileService.getFile(file); diff --git a/src/file/file.module.ts b/src/file/file.module.ts index 84a01dee..a93f2a9a 100644 --- a/src/file/file.module.ts +++ b/src/file/file.module.ts @@ -7,6 +7,6 @@ import { FileService } from './file.service'; @Module({ imports: [UsersModule, HttpClientModule], controllers: [FileController], - providers: [FileService], + providers: [FileService] }) export class FileModule {} diff --git a/src/file/file.service.spec.ts b/src/file/file.service.spec.ts index 3b3583c0..8aa5bae1 100644 --- a/src/file/file.service.spec.ts +++ b/src/file/file.service.spec.ts @@ -6,7 +6,7 @@ describe('FileService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [FileService], + providers: [FileService] }).compile(); service = module.get(FileService); diff --git a/src/httpclient/httpclient.module.ts b/src/httpclient/httpclient.module.ts index 5845ee57..15bb5820 100644 --- a/src/httpclient/httpclient.module.ts +++ b/src/httpclient/httpclient.module.ts @@ -3,6 +3,6 @@ import { HttpClientService } from './httpclient.service'; @Module({ providers: [HttpClientService], - exports: [HttpClientService], + exports: [HttpClientService] }) export class HttpClientModule {} diff --git a/src/httpclient/httpclient.service.spec.ts b/src/httpclient/httpclient.service.spec.ts index aba33a7f..aebaf3d2 100644 --- a/src/httpclient/httpclient.service.spec.ts +++ b/src/httpclient/httpclient.service.spec.ts @@ -6,7 +6,7 @@ describe('HttpclientService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [HttpClientService], + providers: [HttpClientService] }).compile(); service = module.get(HttpClientService); diff --git a/src/httpclient/httpclient.service.ts b/src/httpclient/httpclient.service.ts index afe5f4dc..840241c7 100644 --- a/src/httpclient/httpclient.service.ts +++ b/src/httpclient/httpclient.service.ts @@ -7,7 +7,7 @@ export class HttpClientService { async loadJSON(url: string): Promise { const resp = await axios.get(url, { - responseType: 'json', + responseType: 'json' }); if (resp.status != 200) { throw new Error(`Failed to load url: ${url}. Status ${resp.status}`); @@ -15,7 +15,7 @@ export class HttpClientService { this.log.debug( `Loaded: ${ typeof resp.data === 'string' ? resp.data : JSON.stringify(resp.data) - }`, + }` ); return resp.data; } @@ -23,7 +23,7 @@ export class HttpClientService { async post( url: string, data: unknown, - config?: AxiosRequestConfig, + config?: AxiosRequestConfig ): Promise { const resp = await axios.post(url, data, config); if (![200, 201].includes(+resp.status)) { @@ -44,7 +44,7 @@ export class HttpClientService { async loadPlain(url: string): Promise { const resp = await axios.get(url, { - responseType: 'arraybuffer', + responseType: 'arraybuffer' }); if (resp.status != 200) { @@ -62,7 +62,7 @@ export class HttpClientService { contentType: string; }> { const resp = await axios.get(url, { - responseType: 'arraybuffer', + responseType: 'arraybuffer' }); if (resp.status != 200) { @@ -73,7 +73,7 @@ export class HttpClientService { return { content: buffer, - contentType: resp.headers['content-type'], + contentType: resp.headers['content-type'] }; } } diff --git a/src/keycloak/keycloak.config.properties.ts b/src/keycloak/keycloak.config.properties.ts index e865f44b..017d04e7 100644 --- a/src/keycloak/keycloak.config.properties.ts +++ b/src/keycloak/keycloak.config.properties.ts @@ -4,5 +4,5 @@ export enum KeyCloakConfigProperties { ENV_KEYCLOAK_PUBLIC_CLIENT_ID = 'KEYCLOAK_PUBLIC_CLIENT_ID', ENV_KEYCLOAK_PUBLIC_CLIENT_SECRET = 'KEYCLOAK_PUBLIC_CLIENT_SECRET', ENV_KEYCLOAK_ADMIN_CLIENT_ID = 'KEYCLOAK_ADMIN_CLIENT_ID', - ENV_KEYCLOAK_ADMIN_CLIENT_SECRET = 'KEYCLOAK_ADMIN_CLIENT_SECRET', + ENV_KEYCLOAK_ADMIN_CLIENT_SECRET = 'KEYCLOAK_ADMIN_CLIENT_SECRET' } diff --git a/src/keycloak/keycloak.module.ts b/src/keycloak/keycloak.module.ts index a300d09a..2296b5f0 100644 --- a/src/keycloak/keycloak.module.ts +++ b/src/keycloak/keycloak.module.ts @@ -5,6 +5,6 @@ import { KeyCloakService } from './keycloak.service'; @Module({ imports: [], providers: [KeyCloakService, HttpClientService], - exports: [KeyCloakService, HttpClientService], + exports: [KeyCloakService, HttpClientService] }) export class KeyCloakModule {} diff --git a/src/keycloak/keycloak.service.ts b/src/keycloak/keycloak.service.ts index df370e24..c5f1620d 100644 --- a/src/keycloak/keycloak.service.ts +++ b/src/keycloak/keycloak.service.ts @@ -3,7 +3,7 @@ import { InternalServerErrorException, Logger, OnModuleInit, - UnauthorizedException, + UnauthorizedException } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { ok } from 'assert'; @@ -49,7 +49,7 @@ export interface Token { export enum ClientType { ADMIN = 'admin', - PUBLIC = 'public', + PUBLIC = 'public' } interface ClientCredentials { @@ -69,13 +69,13 @@ export class KeyCloakService implements OnModuleInit { constructor( private readonly configService: ConfigService, - private readonly httpClient: HttpClientService, + private readonly httpClient: HttpClientService ) { this.server_uri = this.configService.get( - KeyCloakConfigProperties.ENV_KEYCLOAK_SERVER_URI, + KeyCloakConfigProperties.ENV_KEYCLOAK_SERVER_URI ); this.realm = this.configService.get( - KeyCloakConfigProperties.ENV_KEYCLOAK_REALM, + KeyCloakConfigProperties.ENV_KEYCLOAK_REALM ); const metadata_url = `${this.server_uri}/realms/${this.realm}/.well-known/openid-configuration`; @@ -83,21 +83,21 @@ export class KeyCloakService implements OnModuleInit { this.clientPublic = { metadata_url, client_id: this.configService.get( - KeyCloakConfigProperties.ENV_KEYCLOAK_PUBLIC_CLIENT_ID, + KeyCloakConfigProperties.ENV_KEYCLOAK_PUBLIC_CLIENT_ID ), client_secret: this.configService.get( - KeyCloakConfigProperties.ENV_KEYCLOAK_PUBLIC_CLIENT_SECRET, - ), + KeyCloakConfigProperties.ENV_KEYCLOAK_PUBLIC_CLIENT_SECRET + ) }; this.clientAdmin = { metadata_url, client_id: this.configService.get( - KeyCloakConfigProperties.ENV_KEYCLOAK_ADMIN_CLIENT_ID, + KeyCloakConfigProperties.ENV_KEYCLOAK_ADMIN_CLIENT_ID ), client_secret: this.configService.get( - KeyCloakConfigProperties.ENV_KEYCLOAK_ADMIN_CLIENT_SECRET, - ), + KeyCloakConfigProperties.ENV_KEYCLOAK_ADMIN_CLIENT_SECRET + ) }; } @@ -117,19 +117,19 @@ export class KeyCloakService implements OnModuleInit { if (!pems.has(kid)) { throw new UnauthorizedException( - 'Authorization header contains an invalid JWT token.', + 'Authorization header contains an invalid JWT token.' ); } return verify(token, pems.get(kid), { - issuer: this.config.issuer, + issuer: this.config.issuer }); } public async introspectToken(token: string): Promise> { ok( (this.config as OIDCIdentityConfig).introspection_endpoint, - 'Missing "introspection_endpoint"', + 'Missing "introspection_endpoint"' ); const { access_token, token_type } = await this.generateToken(); @@ -138,8 +138,8 @@ export class KeyCloakService implements OnModuleInit { return this.httpClient.post(this.config.introspection_endpoint, data, { headers: { Authorization: `${token_type} ${access_token}`, - 'Content-Type': 'application/x-www-form-urlencoded', - }, + 'Content-Type': 'application/x-www-form-urlencoded' + } }); } @@ -147,7 +147,7 @@ export class KeyCloakService implements OnModuleInit { firstName, lastName, email, - password, + password }: RegisterUserData): Promise { this.log.debug(`Called registerUser`); @@ -165,33 +165,33 @@ export class KeyCloakService implements OnModuleInit { { type: 'password', value: password, - temporary: false, - }, - ], + temporary: false + } + ] }, { headers: { 'Content-Type': 'application/json', - Authorization: `${token_type} ${access_token}`, + Authorization: `${token_type} ${access_token}` }, - responseType: 'json', - }, + responseType: 'json' + } ); } public async generateToken(tokenData?: GenerateTokenData): Promise { const tokenPayload = { - ...this.clientAdmin, + ...this.clientAdmin }; if (tokenData) { Object.assign(tokenPayload, { ...tokenData, - grant_type: 'password', + grant_type: 'password' }); } else { Object.assign(tokenPayload, { - grant_type: 'client_credentials', + grant_type: 'client_credentials' }); } @@ -200,10 +200,10 @@ export class KeyCloakService implements OnModuleInit { stringify(tokenPayload), { headers: { - 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Type': 'application/x-www-form-urlencoded' }, - responseType: 'json', - }, + responseType: 'json' + } ); } @@ -219,7 +219,7 @@ export class KeyCloakService implements OnModuleInit { for (;;) { try { this.config = (await this.httpClient.loadJSON( - this.clientAdmin.metadata_url, + this.clientAdmin.metadata_url )) as OIDCIdentityConfig; return; @@ -228,7 +228,7 @@ export class KeyCloakService implements OnModuleInit { if (count >= 10) { throw new Error( - `Cannot discover medata from ${this.clientAdmin.metadata_url}. Got error: ${err}`, + `Cannot discover medata from ${this.clientAdmin.metadata_url}. Got error: ${err}` ); } @@ -246,12 +246,12 @@ export class KeyCloakService implements OnModuleInit { if (!data.keys) { throw new InternalServerErrorException( - 'Internal error occurred downloading JWKS data.', + 'Internal error occurred downloading JWKS data.' ); } const jwks = new Map( - data.keys.map((key: JWK & { kid: string }) => [key.kid, jwkToPem(key)]), + data.keys.map((key: JWK & { kid: string }) => [key.kid, jwkToPem(key)]) ); return jwks; } diff --git a/src/main.ts b/src/main.ts index 69a97476..056e71da 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,7 +10,7 @@ import { readFileSync, readFile, readdirSync } from 'fs'; import cluster from 'cluster'; import { FastifyAdapter, - NestFastifyApplication, + NestFastifyApplication } from '@nestjs/platform-fastify'; import fmp from '@fastify/multipart'; import { randomBytes } from 'crypto'; @@ -48,7 +48,7 @@ const renderDirList: ListRender = (dirs, files) => { - - `, + ` )}
${files.map( @@ -63,7 +63,7 @@ const renderDirList: ListRender = (dirs, files) => { ${file.stats.size} - `, + ` )}
@@ -82,13 +82,13 @@ async function bootstrap() { process.env.NODE_ENV === 'production' ? { cert: readFileSync( - '/etc/letsencrypt/live/brokencrystals.com/fullchain.pem', + '/etc/letsencrypt/live/brokencrystals.com/fullchain.pem' ), key: readFileSync( - '/etc/letsencrypt/live/brokencrystals.com/privkey.pem', - ), + '/etc/letsencrypt/live/brokencrystals.com/privkey.pem' + ) } - : null, + : null }); server.setDefaultRoute((req, res) => { @@ -99,9 +99,9 @@ async function bootstrap() { success: false, error: { kind: 'user_input', - message: 'Not Found', - }, - }), + message: 'Not Found' + } + }) ); } @@ -117,7 +117,7 @@ async function bootstrap() { res.statusCode = 200; res.setHeader('Content-Type', 'text/html'); res.end(data); - }, + } ); }); @@ -127,7 +127,7 @@ async function bootstrap() { decorateReply: false, redirect: false, wildcard: false, - serveDotFiles: true, + serveDotFiles: true }); for (const dir of readdirSync(join(__dirname, '..', 'client', 'vcs'))) { @@ -139,9 +139,9 @@ async function bootstrap() { index: false, list: { format: 'html', - render: renderDirList, + render: renderDirList }, - serveDotFiles: true, + serveDotFiles: true }); } @@ -153,9 +153,9 @@ async function bootstrap() { index: false, list: { format: 'html', - render: renderDirList, + render: renderDirList }, - serveDotFiles: true, + serveDotFiles: true }); const app: NestFastifyApplication = await NestFactory.create( @@ -165,8 +165,8 @@ async function bootstrap() { logger: process.env.NODE_ENV === 'production' ? ['error'] - : ['debug', 'log', 'warn', 'error'], - }, + : ['debug', 'log', 'warn', 'error'] + } ); await server.register(fastifyCookie); @@ -176,8 +176,8 @@ async function bootstrap() { cookieName: 'connect.sid', cookie: { secure: false, - httpOnly: false, - }, + httpOnly: false + } }); server.addContentTypeParser('*', (req) => rawbody(req.raw)); @@ -220,7 +220,7 @@ async function bootstrap() { * [Chat](#/Chat%20controller) — operations with chat - `, + ` ) .setVersion('1.0') .addServer(process.env.URL) @@ -242,7 +242,7 @@ if (cluster.isPrimary && process.env.NODE_ENV === 'production') { cluster.on('exit', (worker, code, signal) => { console.log( - `Worker ${worker.process.pid} died with code ${code} and signal ${signal}`, + `Worker ${worker.process.pid} died with code ${code} and signal ${signal}` ); console.log('Starting a new worker'); cluster.fork(); diff --git a/src/model/user.entity.ts b/src/model/user.entity.ts index 5853f812..3cf58377 100644 --- a/src/model/user.entity.ts +++ b/src/model/user.entity.ts @@ -21,7 +21,7 @@ export class User extends Base { @Property({ nullable: true, - type: BlobType, + type: BlobType }) photo: Buffer; diff --git a/src/orm/orm.config.factory.ts b/src/orm/orm.config.factory.ts index c1b819dc..6cd81e17 100644 --- a/src/orm/orm.config.factory.ts +++ b/src/orm/orm.config.factory.ts @@ -19,27 +19,27 @@ export class OrmConfigFactory { entities: ['dist/model'], entitiesTs: ['src/model'], host: this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_HOST, + OrmModuleConfigProperties.ENV_DATABASE_HOST ), dbName: this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_SCHEMA, + OrmModuleConfigProperties.ENV_DATABASE_SCHEMA ), user: this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_USER, + OrmModuleConfigProperties.ENV_DATABASE_USER ), password: this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_PASSWORD, + OrmModuleConfigProperties.ENV_DATABASE_PASSWORD ), port: this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_PORT, + OrmModuleConfigProperties.ENV_DATABASE_PORT ), metadataProvider: ReflectMetadataProvider, highlighter: new SqlHighlighter(), debug: this.configService.get( - OrmModuleConfigProperties.ENV_DATABASE_PORT, + OrmModuleConfigProperties.ENV_DATABASE_PORT ) === 'true', - logger: logger.log.bind(logger), + logger: logger.log.bind(logger) }); return config; diff --git a/src/orm/orm.module.config.properties.ts b/src/orm/orm.module.config.properties.ts index ec9c31e9..c7a0a099 100644 --- a/src/orm/orm.module.config.properties.ts +++ b/src/orm/orm.module.config.properties.ts @@ -4,5 +4,5 @@ export enum OrmModuleConfigProperties { ENV_DATABASE_USER = 'DATABASE_USER', ENV_DATABASE_PASSWORD = 'DATABASE_PASSWORD', ENV_DATABASE_PORT = 'DATABASE_PORT', - ENV_DATABASE_DEBUG = 'DATABASE_DEBUG', + ENV_DATABASE_DEBUG = 'DATABASE_DEBUG' } diff --git a/src/orm/orm.module.ts b/src/orm/orm.module.ts index 97565fac..d98fc06f 100644 --- a/src/orm/orm.module.ts +++ b/src/orm/orm.module.ts @@ -11,12 +11,12 @@ import { Product } from '../model/product.entity'; MikroOrmModule.forRootAsync({ inject: [ConfigService], useFactory: async (configService: ConfigService) => - new OrmConfigFactory(configService).buildConfig(), + new OrmConfigFactory(configService).buildConfig() }), MikroOrmModule.forFeature({ - entities: [Testimonial, User, Product], - }), + entities: [Testimonial, User, Product] + }) ], - exports: [MikroOrmModule], + exports: [MikroOrmModule] }) export class OrmModule {} diff --git a/src/partners/partners.controller.ts b/src/partners/partners.controller.ts index f3166bfb..ea74a771 100644 --- a/src/partners/partners.controller.ts +++ b/src/partners/partners.controller.ts @@ -5,18 +5,18 @@ import { HttpException, HttpStatus, Logger, - Query, + Query } from '@nestjs/common'; import { ApiOkResponse, ApiOperation, ApiQuery, - ApiTags, + ApiTags } from '@nestjs/swagger'; import { API_DESC_QUERY_PARTNERS_RAW, API_DESC_PARTNERS_LOGIN, - API_DESC_SEARCH_PARTNERS_NAMES, + API_DESC_SEARCH_PARTNERS_NAMES } from './partners.controller.swagger.desc'; import { PartnersService } from './partners.service'; @@ -33,14 +33,14 @@ export class PartnersController { name: 'xpath', type: 'string', example: '/partners/partner/name', - required: true, + required: true }) @Header('content-type', 'text/xml') @ApiOperation({ - description: API_DESC_QUERY_PARTNERS_RAW, + description: API_DESC_QUERY_PARTNERS_RAW }) @ApiOkResponse({ - type: String, + type: String }) async queryPartnersRaw(@Query('xpath') xpath: string): Promise { this.logger.debug(`Getting partners with xpath expression "${xpath}"`); @@ -50,7 +50,7 @@ export class PartnersController { } catch (err) { throw new HttpException( `Failed to load XML using XPATH. Details: ${err}`, - HttpStatus.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR ); } } @@ -61,27 +61,27 @@ export class PartnersController { name: 'username', type: 'string', example: 'walter100', - required: true, + required: true }) @ApiQuery({ name: 'password', type: 'string', example: 'Heisenberg123', - required: true, + required: true }) @Header('content-type', 'text/xml') @ApiOperation({ - description: API_DESC_PARTNERS_LOGIN, + description: API_DESC_PARTNERS_LOGIN }) @ApiOkResponse({ - type: String, + type: String }) async partnerLogin( @Query('username') username: string, - @Query('password') password: string, + @Query('password') password: string ): Promise { this.logger.debug( - `Trying to login partner with username ${username} using password ${password}`, + `Trying to login partner with username ${username} using password ${password}` ); try { @@ -104,7 +104,7 @@ export class PartnersController { throw new HttpException( `Access denied to partner's account. ${errorMessage}`, - HttpStatus.FORBIDDEN, + HttpStatus.FORBIDDEN ); } } @@ -115,14 +115,14 @@ export class PartnersController { name: 'keyword', type: 'string', example: 'Walter', - required: true, + required: true }) @Header('content-type', 'text/xml') @ApiOperation({ - description: API_DESC_SEARCH_PARTNERS_NAMES, + description: API_DESC_SEARCH_PARTNERS_NAMES }) @ApiOkResponse({ - type: String, + type: String }) async searchPartners(@Query('keyword') keyword: string): Promise { this.logger.debug(`Searching partner names by the keyword "${keyword}"`); @@ -140,7 +140,7 @@ export class PartnersController { throw new HttpException( `Couldn't find partners. ${errorMessage}`, - HttpStatus.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR ); } } diff --git a/src/partners/partners.module.ts b/src/partners/partners.module.ts index 7adebc48..7524f479 100644 --- a/src/partners/partners.module.ts +++ b/src/partners/partners.module.ts @@ -5,6 +5,6 @@ import { PartnersController } from './partners.controller'; @Module({ providers: [PartnersService], controllers: [PartnersController], - exports: [PartnersService], + exports: [PartnersService] }) export class PartnersModule {} diff --git a/src/partners/partners.service.spec.ts b/src/partners/partners.service.spec.ts index fcf5393b..fcb4e014 100644 --- a/src/partners/partners.service.spec.ts +++ b/src/partners/partners.service.spec.ts @@ -6,7 +6,7 @@ describe('PartnersService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [PartnersService], + providers: [PartnersService] }).compile(); service = module.get(PartnersService); diff --git a/src/partners/partners.service.ts b/src/partners/partners.service.ts index 7c7025cb..461a74b8 100644 --- a/src/partners/partners.service.ts +++ b/src/partners/partners.service.ts @@ -55,13 +55,13 @@ export class PartnersService { private getPartnersXMLObj(): Node { const partnersXMLObj = new DOMParser().parseFromString( this.XML_AUTHORS_STR, - 'text/xml', + 'text/xml' ); return partnersXMLObj; } private selectPartnerPropertiesByXPATH( - xpathExpression: string, + xpathExpression: string ): SelectReturnType { const partnersXMLObj = this.getPartnersXMLObj(); return xpath.select(xpathExpression, partnersXMLObj); @@ -76,7 +76,7 @@ export class PartnersService { if (!Array.isArray(xmlNodes)) { this.logger.debug( - `xmlNodes's type wasn't 'Array', and it's value was: ${xmlNodes}`, + `xmlNodes's type wasn't 'Array', and it's value was: ${xmlNodes}` ); xmlNodes = []; } else { diff --git a/src/products/api/ProductDto.ts b/src/products/api/ProductDto.ts index d5dc4ba4..6e62a2c2 100644 --- a/src/products/api/ProductDto.ts +++ b/src/products/api/ProductDto.ts @@ -10,7 +10,7 @@ export class ProductDto { @ApiProperty({ default: '/api/file?path=config/products/crystals/amethyst.jpg&type=image/jpg', - required: true, + required: true }) photoUrl: string; diff --git a/src/products/products.controller.ts b/src/products/products.controller.ts index 624aa43a..f8720c82 100644 --- a/src/products/products.controller.ts +++ b/src/products/products.controller.ts @@ -6,7 +6,7 @@ import { Headers, InternalServerErrorException, Query, - BadRequestException, + BadRequestException } from '@nestjs/common'; import { ApiOperation, @@ -15,7 +15,7 @@ import { ApiForbiddenResponse, ApiInternalServerErrorResponse, ApiHeader, - ApiQuery, + ApiQuery } from '@nestjs/swagger'; import { AuthGuard } from '../auth/auth.guard'; import { JwtProcessorType } from '../auth/auth.service'; @@ -26,7 +26,7 @@ import { Product } from '../model/product.entity'; import { API_DESC_GET_LATEST_PRODUCTS, API_DESC_GET_PRODUCTS, - API_DESC_GET_VIEW_PRODUCT, + API_DESC_GET_VIEW_PRODUCT } from './products.controller.api.desc'; @Controller('/api/products') @@ -49,11 +49,11 @@ export class ProductsController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: API_DESC_GET_PRODUCTS, + description: API_DESC_GET_PRODUCTS }) @ApiOkResponse({ type: ProductDto, - isArray: true, + isArray: true }) @ApiForbiddenResponse({ schema: { @@ -61,15 +61,15 @@ export class ProductsController { properties: { statusCode: { type: 'number' }, message: { type: 'string' }, - error: { type: 'string' }, - }, - }, + error: { type: 'string' } + } + } }) @ApiQuery({ name: 'date_from', example: '02-05-2001', required: false }) @ApiQuery({ name: 'date_to', example: '02-05-2024', required: false }) async getProducts( @Query('date_from') dateFrom: string, - @Query('date_to') dateTo: string, + @Query('date_to') dateTo: string ): Promise { this.logger.debug('Get all products.'); let df = new Date(new Date().setFullYear(new Date().getFullYear() - 1)); @@ -92,14 +92,14 @@ export class ProductsController { @Get('latest') @ApiQuery({ name: 'limit', example: 3, required: false }) @ApiOperation({ - description: API_DESC_GET_LATEST_PRODUCTS, + description: API_DESC_GET_LATEST_PRODUCTS }) @ApiOkResponse({ type: ProductDto, - isArray: true, + isArray: true }) async getLatestProducts( - @Query('limit') limit: number, + @Query('limit') limit: number ): Promise { this.logger.debug('Get latest products.'); if (limit && isNaN(limit)) { @@ -115,7 +115,7 @@ export class ProductsController { @Get('views') @ApiHeader({ name: 'x-product-name', example: 'Amethyst' }) @ApiOperation({ - description: API_DESC_GET_VIEW_PRODUCT, + description: API_DESC_GET_VIEW_PRODUCT }) @ApiOkResponse() @ApiInternalServerErrorResponse({ @@ -123,12 +123,12 @@ export class ProductsController { type: 'object', properties: { error: { type: 'string' }, - location: { type: 'string' }, - }, - }, + location: { type: 'string' } + } + } }) async viewProduct( - @Headers('x-product-name') productName: string, + @Headers('x-product-name') productName: string ): Promise { try { const query = `UPDATE product SET views_count = views_count + 1 WHERE name = '${productName}'`; @@ -136,7 +136,7 @@ export class ProductsController { } catch (err) { throw new InternalServerErrorException({ error: err.message, - location: __filename, + location: __filename }); } } diff --git a/src/products/products.module.ts b/src/products/products.module.ts index 307cbfeb..b43b048f 100644 --- a/src/products/products.module.ts +++ b/src/products/products.module.ts @@ -10,6 +10,6 @@ import { ProductsResolver } from './products.resolver'; imports: [OrmModule, AuthModule, UsersModule], controllers: [ProductsController], providers: [ProductsService, ProductsResolver], - exports: [ProductsService], + exports: [ProductsService] }) export class ProductsModule {} diff --git a/src/products/products.resolver.ts b/src/products/products.resolver.ts index b5354533..951d6b70 100644 --- a/src/products/products.resolver.ts +++ b/src/products/products.resolver.ts @@ -9,7 +9,7 @@ import { ProductsService } from './products.service'; import { API_DESC_GET_LATEST_PRODUCTS, API_DESC_GET_PRODUCTS, - API_DESC_GET_VIEW_PRODUCT, + API_DESC_GET_VIEW_PRODUCT } from './products.controller.api.desc'; @Resolver(() => Product) @@ -25,7 +25,7 @@ export class ProductsResolver { } @Query(() => [Product], { - description: API_DESC_GET_LATEST_PRODUCTS, + description: API_DESC_GET_LATEST_PRODUCTS }) async latestProducts(): Promise { const products = await this.productsService.findLatest(3); @@ -33,10 +33,10 @@ export class ProductsResolver { } @Mutation(() => Boolean, { - description: API_DESC_GET_VIEW_PRODUCT, + description: API_DESC_GET_VIEW_PRODUCT }) async viewProduct( - @Args('productName') productName: string, + @Args('productName') productName: string ): Promise { try { const query = `UPDATE product SET views_count = views_count + 1 WHERE name = '${productName}'`; @@ -45,7 +45,7 @@ export class ProductsResolver { } catch (err) { throw new InternalServerErrorException({ error: err.message, - location: __filename, + location: __filename }); } } diff --git a/src/products/products.service.ts b/src/products/products.service.ts index 2a1ff739..02d3fa61 100644 --- a/src/products/products.service.ts +++ b/src/products/products.service.ts @@ -3,7 +3,7 @@ import { InjectRepository } from '@mikro-orm/nestjs'; import { Injectable, InternalServerErrorException, - Logger, + Logger } from '@nestjs/common'; import { Product } from '../model/product.entity'; @@ -14,7 +14,7 @@ export class ProductsService { constructor( @InjectRepository(Product) private readonly productsRepository: EntityRepository, - private readonly em: EntityManager, + private readonly em: EntityManager ) {} private sleep(ms: number): Promise { @@ -23,9 +23,9 @@ export class ProductsService { async findAll( dateFrom: Date = new Date( - new Date().setFullYear(new Date().getFullYear() - 1), + new Date().setFullYear(new Date().getFullYear() - 1) ), - dateTo: Date = new Date(), + dateTo: Date = new Date() ): Promise { this.logger.debug(`Find all products from ${dateFrom} to ${dateTo}`); const diffInMilliseconds = Math.abs(dateTo.getTime() - dateFrom.getTime()); @@ -36,9 +36,9 @@ export class ProductsService { } return this.productsRepository.find( { - createdAt: { $gte: dateFrom, $lte: dateTo }, + createdAt: { $gte: dateFrom, $lte: dateTo } }, - { orderBy: { createdAt: 'desc' } }, + { orderBy: { createdAt: 'desc' } } ); } @@ -46,7 +46,7 @@ export class ProductsService { this.logger.debug(`Find ${limit} latest products`); return this.productsRepository.find( {}, - { limit, orderBy: { createdAt: 'desc' } }, + { limit, orderBy: { createdAt: 'desc' } } ); } diff --git a/src/subscriptions/subscriptions.controller.spec.ts b/src/subscriptions/subscriptions.controller.spec.ts index a42f3811..577dbbf4 100644 --- a/src/subscriptions/subscriptions.controller.spec.ts +++ b/src/subscriptions/subscriptions.controller.spec.ts @@ -6,7 +6,7 @@ describe('SubscriptionsController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - controllers: [SubscriptionsController], + controllers: [SubscriptionsController] }).compile(); controller = module.get(SubscriptionsController); diff --git a/src/subscriptions/subscriptions.controller.ts b/src/subscriptions/subscriptions.controller.ts index 24e68312..d4b88f6d 100644 --- a/src/subscriptions/subscriptions.controller.ts +++ b/src/subscriptions/subscriptions.controller.ts @@ -3,7 +3,7 @@ import { ApiCreatedResponse, ApiOperation, ApiQuery, - ApiTags, + ApiTags } from '@nestjs/swagger'; import { SWAGGER_DESC_CREATE_SUBSCRIPTION } from './subscriptions.controller.swagger.desc'; @@ -16,13 +16,13 @@ export class SubscriptionsController { @ApiQuery({ name: 'email', example: 'john.doe@example.com', - required: true, + required: true }) @ApiOperation({ - description: SWAGGER_DESC_CREATE_SUBSCRIPTION, + description: SWAGGER_DESC_CREATE_SUBSCRIPTION }) @ApiCreatedResponse({ - description: 'Returns subscribed email', + description: 'Returns subscribed email' }) async subscribe(@Query('email') email: string): Promise { this.logger.log(`Subscribed with email ${email}`); diff --git a/src/subscriptions/subscriptions.module.ts b/src/subscriptions/subscriptions.module.ts index fd7daa54..aa6e9625 100644 --- a/src/subscriptions/subscriptions.module.ts +++ b/src/subscriptions/subscriptions.module.ts @@ -2,6 +2,6 @@ import { Module } from '@nestjs/common'; import { SubscriptionsController } from './subscriptions.controller'; @Module({ - controllers: [SubscriptionsController], + controllers: [SubscriptionsController] }) export class SubscriptionsModule {} diff --git a/src/testimonials/api/TestimonialDto.ts b/src/testimonials/api/TestimonialDto.ts index 981312c7..a1ce36fe 100644 --- a/src/testimonials/api/TestimonialDto.ts +++ b/src/testimonials/api/TestimonialDto.ts @@ -15,7 +15,7 @@ export class TestimonialDto { return { message: t.message, name: t.name, - title: t.title, + title: t.title }; } } diff --git a/src/testimonials/testimonials.controller.spec.ts b/src/testimonials/testimonials.controller.spec.ts index fa140847..fb5c6fe2 100644 --- a/src/testimonials/testimonials.controller.spec.ts +++ b/src/testimonials/testimonials.controller.spec.ts @@ -12,13 +12,13 @@ describe('TestimonialsController', () => { providers: [ { provide: TestimonialsService, - useValue: {}, + useValue: {} }, { provide: AuthService, - useValue: {}, - }, - ], + useValue: {} + } + ] }).compile(); controller = module.get(TestimonialsController); diff --git a/src/testimonials/testimonials.controller.ts b/src/testimonials/testimonials.controller.ts index 90749ce0..a8ec7c3f 100644 --- a/src/testimonials/testimonials.controller.ts +++ b/src/testimonials/testimonials.controller.ts @@ -6,7 +6,7 @@ import { Logger, Post, Query, - UseGuards, + UseGuards } from '@nestjs/common'; import { ApiBody, @@ -14,7 +14,7 @@ import { ApiOkResponse, ApiOperation, ApiQuery, - ApiTags, + ApiTags } from '@nestjs/swagger'; import { AuthGuard } from '../auth/auth.guard'; import { JwtProcessorType } from '../auth/auth.service'; @@ -24,7 +24,7 @@ import { TestimonialDto } from './api/TestimonialDto'; import { API_DESC_CREATE_TESTIMONIAL, API_DESC_GET_TESTIMONIALS, - API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY, + API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY } from './testimonials.controller.api.desc'; import { TestimonialsService } from './testimonials.service'; @@ -37,15 +37,15 @@ export class TestimonialsController { @Post() @ApiBody({ - type: TestimonialDto, + type: TestimonialDto }) @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: API_DESC_CREATE_TESTIMONIAL, + description: API_DESC_CREATE_TESTIMONIAL }) @ApiOkResponse({ - type: TestimonialDto, + type: TestimonialDto }) @ApiForbiddenResponse({ schema: { @@ -53,35 +53,35 @@ export class TestimonialsController { properties: { statusCode: { type: 'number' }, message: { type: 'string' }, - error: { type: 'string' }, - }, - }, + error: { type: 'string' } + } + } }) async createTestimonial( - @Body() req: CreateTestimonialRequest, + @Body() req: CreateTestimonialRequest ): Promise { this.logger.debug('Create testimonial.'); return TestimonialDto.covertToApi( await this.testimonialsService.createTestimonial( req.message, req.name, - req.title, - ), + req.title + ) ); } @Get() @ApiOperation({ - description: API_DESC_GET_TESTIMONIALS, + description: API_DESC_GET_TESTIMONIALS }) @ApiOkResponse({ type: TestimonialDto, - isArray: true, + isArray: true }) async getTestimonials(): Promise { this.logger.debug('Get all testimonials.'); return (await this.testimonialsService.findAll()).map( - TestimonialDto.covertToApi, + TestimonialDto.covertToApi ); } @@ -89,14 +89,14 @@ export class TestimonialsController { @ApiQuery({ name: 'query', example: 'select count(*) as count from testimonial', - required: true, + required: true }) @Header('content-type', 'text/html') @ApiOperation({ - description: API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY, + description: API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY }) @ApiOkResponse({ - type: String, + type: String }) async getCount(@Query('query') query: string): Promise { this.logger.debug('Get count of testimonials.'); diff --git a/src/testimonials/testimonials.module.ts b/src/testimonials/testimonials.module.ts index adbfa708..2828faa4 100644 --- a/src/testimonials/testimonials.module.ts +++ b/src/testimonials/testimonials.module.ts @@ -10,6 +10,6 @@ import { TestimonialsService } from './testimonials.service'; imports: [OrmModule, AuthModule, UsersModule], controllers: [TestimonialsController], providers: [TestimonialsService, TestimonialsResolver], - exports: [TestimonialsService], + exports: [TestimonialsService] }) export class TestimonialsModule {} diff --git a/src/testimonials/testimonials.resolver.ts b/src/testimonials/testimonials.resolver.ts index e0981d8a..c0f50108 100644 --- a/src/testimonials/testimonials.resolver.ts +++ b/src/testimonials/testimonials.resolver.ts @@ -1,7 +1,7 @@ import { InternalServerErrorException, Logger, - UseGuards, + UseGuards } from '@nestjs/common'; import { AuthGuard } from '../auth/auth.guard'; import { JwtProcessorType } from '../auth/auth.service'; @@ -14,7 +14,7 @@ import { CreateTestimonialRequest } from './api/CreateTestimonialRequestGQL'; import { API_DESC_CREATE_TESTIMONIAL, API_DESC_GET_TESTIMONIALS, - API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY, + API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY } from './testimonials.controller.api.desc'; @Resolver(() => Testimonial) @@ -24,17 +24,17 @@ export class TestimonialsResolver { constructor(private readonly testimonialsService: TestimonialsService) {} @Query(() => [Testimonial], { - description: API_DESC_GET_TESTIMONIALS, + description: API_DESC_GET_TESTIMONIALS }) async allTestimonials(): Promise { this.logger.debug('Get all testimonials'); return (await this.testimonialsService.findAll()).map( - TestimonialDto.covertToApi, + TestimonialDto.covertToApi ); } @Query(() => Int, { - description: API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY, + description: API_DESC_GET_TESTIMONIALS_ON_SQL_QUERY }) testimonialsCount(@Args('query') query: string): Promise { this.logger.debug('Get count of testimonials'); @@ -42,12 +42,12 @@ export class TestimonialsResolver { } @Mutation(() => Testimonial, { - description: API_DESC_CREATE_TESTIMONIAL, + description: API_DESC_CREATE_TESTIMONIAL }) @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) async createTestimonial( - @Args('testimonialRequest') testimonialRequest: CreateTestimonialRequest, + @Args('testimonialRequest') testimonialRequest: CreateTestimonialRequest ) { this.logger.debug('Create testimonial'); try { @@ -55,8 +55,8 @@ export class TestimonialsResolver { await this.testimonialsService.createTestimonial( testimonialRequest.message, testimonialRequest.name, - testimonialRequest.title, - ), + testimonialRequest.title + ) ); } catch { throw InternalServerErrorException; diff --git a/src/testimonials/testimonials.service.spec.ts b/src/testimonials/testimonials.service.spec.ts index c5e457ac..53a9bc04 100644 --- a/src/testimonials/testimonials.service.spec.ts +++ b/src/testimonials/testimonials.service.spec.ts @@ -13,13 +13,13 @@ describe('TestimonialsService', () => { TestimonialsService, { provide: EntityManager, - useValue: {}, + useValue: {} }, { provide: getRepositoryToken(Testimonial), - useValue: {}, - }, - ], + useValue: {} + } + ] }).compile(); service = module.get(TestimonialsService); diff --git a/src/testimonials/testimonials.service.ts b/src/testimonials/testimonials.service.ts index 7a445c65..bd2942d8 100644 --- a/src/testimonials/testimonials.service.ts +++ b/src/testimonials/testimonials.service.ts @@ -11,7 +11,7 @@ export class TestimonialsService { constructor( @InjectRepository(Testimonial) private readonly testimonialsRepository: EntityRepository, - private readonly em: EntityManager, + private readonly em: EntityManager ) {} async findAll(): Promise { @@ -22,15 +22,15 @@ export class TestimonialsService { async createTestimonial( message: string, name: string, - title: string, + title: string ): Promise { this.logger.debug( - `Create a testimonial. Name: ${message}, title: ${title}, message: ${message}`, + `Create a testimonial. Name: ${message}, title: ${title}, message: ${message}` ); const connection = this.em.getConnection(); const legacyTestimonials: Testimonial[] = await connection.execute( - `select * from testimonial where id is not null order by created_at`, + `select * from testimonial where id is not null order by created_at` ); if (legacyTestimonials?.length >= this.MAX_LIMIT) { @@ -39,7 +39,7 @@ export class TestimonialsService { .map((x: Testimonial) => x.id); await connection.execute('delete from testimonial where id not in(?)', [ - ids, + ids ]); } diff --git a/src/users/api/CreateUserRequest.ts b/src/users/api/CreateUserRequest.ts index d650493a..eff15754 100644 --- a/src/users/api/CreateUserRequest.ts +++ b/src/users/api/CreateUserRequest.ts @@ -3,7 +3,7 @@ import { UserDto } from './UserDto'; export enum SignupMode { BASIC = 'basic', - OIDC = 'oidc', + OIDC = 'oidc' } export class CreateUserRequest extends UserDto { diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index dd92175f..38e3e67d 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -13,17 +13,17 @@ describe('UsersController', () => { providers: [ { provide: UsersService, - useValue: {}, + useValue: {} }, { provide: KeyCloakService, - useValue: {}, + useValue: {} }, { provide: AuthService, - useValue: {}, - }, - ], + useValue: {} + } + ] }).compile(); controller = module.get(UsersController); diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 6f901a83..191586e4 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -21,7 +21,7 @@ import { SerializeOptions, UnauthorizedException, UseGuards, - UseInterceptors, + UseInterceptors } from '@nestjs/common'; import { ApiConflictResponse, @@ -33,7 +33,7 @@ import { ApiOperation, ApiQuery, ApiTags, - ApiUnauthorizedResponse, + ApiUnauthorizedResponse } from '@nestjs/swagger'; import { CreateUserRequest, SignupMode } from './api/CreateUserRequest'; import { UserDto } from './api/UserDto'; @@ -58,7 +58,7 @@ import { SWAGGER_DESC_ADMIN_RIGHTS, SWAGGER_DESC_FIND_USERS, SWAGGER_DESC_FIND_FULL_USER_INFO, - SWAGGER_DESC_DELETE_PHOTO_USER_BY_ID, + SWAGGER_DESC_DELETE_PHOTO_USER_BY_ID } from './users.controller.swagger.desc'; import { AdminGuard } from './users.guard'; import { PermissionDto } from './api/PermissionDto'; @@ -74,12 +74,12 @@ export class UsersController { constructor( private readonly usersService: UsersService, - private readonly keyCloakService: KeyCloakService, + private readonly keyCloakService: KeyCloakService ) {} @Options() @ApiOperation({ - description: SWAGGER_DESC_OPTIONS_REQUEST, + description: SWAGGER_DESC_OPTIONS_REQUEST }) @Header('Access-Control-Request-Headers', 'OPTIONS, GET, POST, DELETE') async getTestOptions(): Promise { @@ -90,11 +90,11 @@ export class UsersController { @ApiQuery({ name: 'email', example: 'john.doe@example.com', required: true }) @SerializeOptions({ groups: [BASIC_USER_INFO] }) @ApiOperation({ - description: SWAGGER_DESC_FIND_USER, + description: SWAGGER_DESC_FIND_USER }) @ApiOkResponse({ type: UserDto, - description: 'Returns basic user info if it exists', + description: 'Returns basic user info if it exists' }) @ApiNotFoundResponse({ description: 'User not found', @@ -102,9 +102,9 @@ export class UsersController { type: 'object', properties: { statusCode: { type: 'number' }, - message: { type: 'string' }, - }, - }, + message: { type: 'string' } + } + } }) async getByEmail(@Param('email') email: string): Promise { try { @@ -119,11 +119,11 @@ export class UsersController { @ApiQuery({ name: 'id', example: 1, required: true }) @SerializeOptions({ groups: [BASIC_USER_INFO] }) @ApiOperation({ - description: SWAGGER_DESC_FIND_USER, + description: SWAGGER_DESC_FIND_USER }) @ApiOkResponse({ type: UserDto, - description: 'Returns basic user info if it exists', + description: 'Returns basic user info if it exists' }) @ApiNotFoundResponse({ description: 'User not found', @@ -131,9 +131,9 @@ export class UsersController { type: 'object', properties: { statusCode: { type: 'number' }, - message: { type: 'string' }, - }, - }, + message: { type: 'string' } + } + } }) async getById(@Param('id') id: number): Promise { try { @@ -148,11 +148,11 @@ export class UsersController { @ApiQuery({ name: 'email', example: 'john.doe@example.com', required: true }) @SerializeOptions({ groups: [FULL_USER_INFO] }) @ApiOperation({ - description: SWAGGER_DESC_FIND_FULL_USER_INFO, + description: SWAGGER_DESC_FIND_FULL_USER_INFO }) @ApiOkResponse({ type: UserDto, - description: 'Returns full user info if it exists', + description: 'Returns full user info if it exists' }) @ApiNotFoundResponse({ description: 'User not found', @@ -160,9 +160,9 @@ export class UsersController { type: 'object', properties: { statusCode: { type: 'number' }, - message: { type: 'string' }, - }, - }, + message: { type: 'string' } + } + } }) async getFullUserInfo(@Param('email') email: string): Promise { try { @@ -177,11 +177,11 @@ export class UsersController { @ApiQuery({ name: 'name', example: 'john', required: true }) @SerializeOptions({ groups: [FULL_USER_INFO] }) @ApiOperation({ - description: SWAGGER_DESC_FIND_USERS, + description: SWAGGER_DESC_FIND_USERS }) @ApiOkResponse({ type: UserDto, - description: SWAGGER_DESC_FIND_USERS, + description: SWAGGER_DESC_FIND_USERS }) async searchByName(@Param('name') name: string): Promise { try { @@ -198,27 +198,27 @@ export class UsersController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: SWAGGER_DESC_PHOTO_USER_BY_EMAIL, + description: SWAGGER_DESC_PHOTO_USER_BY_EMAIL }) @ApiOkResponse({ - description: 'Returns user profile photo', + description: 'Returns user profile photo' }) @ApiNoContentResponse({ - description: 'Returns empty content if photo is not set', + description: 'Returns empty content if photo is not set' }) @ApiForbiddenResponse({ - description: 'Returns then user is not authenticated', + description: 'Returns then user is not authenticated' }) async getUserPhoto( @Param('email') email: string, - @Res({ passthrough: true }) res: FastifyReply, + @Res({ passthrough: true }) res: FastifyReply ) { this.logger.debug(`Find a user photo by email: ${email}`); const user = await this.usersService.findByEmail(email); if (!user) { throw new NotFoundException({ error: 'Could not file user', - location: __filename, + location: __filename }); } @@ -232,7 +232,7 @@ export class UsersController { } catch (err) { throw new InternalServerErrorException({ error: err.message, - location: __filename, + location: __filename }); } } @@ -242,23 +242,23 @@ export class UsersController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: SWAGGER_DESC_DELETE_PHOTO_USER_BY_ID, + description: SWAGGER_DESC_DELETE_PHOTO_USER_BY_ID }) @ApiOkResponse({ - description: 'Deletes user profile photo', + description: 'Deletes user profile photo' }) @ApiNoContentResponse({ - description: 'Returns empty content if there was no user profile photo', + description: 'Returns empty content if there was no user profile photo' }) @ApiForbiddenResponse({ - description: 'Returns when user is not authenticated', + description: 'Returns when user is not authenticated' }) @ApiUnauthorizedResponse({ - description: 'Returns when isAdmin is false', + description: 'Returns when isAdmin is false' }) async deleteUserPhotoById( @Param('id') id: number, - @Query('isAdmin') isAdminParam: string, + @Query('isAdmin') isAdminParam: string ) { isAdminParam = isAdminParam.toLowerCase(); const isAdmin = @@ -271,7 +271,7 @@ export class UsersController { if (!user) { throw new NotFoundException({ error: 'Could not file user', - location: __filename, + location: __filename }); } @@ -283,14 +283,14 @@ export class UsersController { name: 'query', example: '(&(objectClass=person)(objectClass=user)(email=john.doe@example.com))', - required: true, + required: true }) @ApiOperation({ - description: SWAGGER_DESC_LDAP_SEARCH, + description: SWAGGER_DESC_LDAP_SEARCH }) @ApiOkResponse({ type: UserDto, - isArray: true, + isArray: true }) async ldapQuery(@Query('query') query: string): Promise { this.logger.debug(`Call ldapQuery: ${query}`); @@ -311,7 +311,7 @@ export class UsersController { } catch (err) { throw new InternalServerErrorException({ error: err.message, - location: __filename, + location: __filename }); } @@ -324,7 +324,7 @@ export class UsersController { @Post('/basic') @ApiOperation({ - description: SWAGGER_DESC_CREATE_BASIC_USER, + description: SWAGGER_DESC_CREATE_BASIC_USER }) @ApiConflictResponse({ schema: { @@ -332,14 +332,14 @@ export class UsersController { properties: { statusCode: { type: 'number' }, message: { type: 'string' }, - error: { type: 'string' }, - }, + error: { type: 'string' } + } }, - description: 'User Already exists', + description: 'User Already exists' }) @ApiCreatedResponse({ type: UserDto, - description: 'User created', + description: 'User created' }) async createUser(@Body() user: CreateUserRequest): Promise { try { @@ -351,31 +351,31 @@ export class UsersController { } return new UserDto( - await this.usersService.createUser(user, user.op === SignupMode.BASIC), + await this.usersService.createUser(user, user.op === SignupMode.BASIC) ); } catch (err) { throw new HttpException( err.message ?? 'Something went wrong', - err.status ?? HttpStatus.INTERNAL_SERVER_ERROR, + err.status ?? HttpStatus.INTERNAL_SERVER_ERROR ); } } @Post('/oidc') @ApiOperation({ - description: SWAGGER_DESC_CREATE_OIDC_USER, + description: SWAGGER_DESC_CREATE_OIDC_USER }) @ApiConflictResponse({ schema: { type: 'object', properties: { - errorMessage: { type: 'string' }, - }, + errorMessage: { type: 'string' } + } }, - description: 'User Already exists', + description: 'User Already exists' }) @ApiCreatedResponse({ - description: 'User created, returns empty object', + description: 'User created, returns empty object' }) async createOIDCUser(@Body() user: CreateUserRequest): Promise { try { @@ -392,8 +392,8 @@ export class UsersController { email: user.email, firstName: user.firstName, lastName: user.lastName, - password: user.password, - }), + password: user.password + }) ); this.createUser(user); @@ -402,7 +402,7 @@ export class UsersController { } catch (err) { throw new HttpException( err.response.data ?? 'Something went wrong', - err.response.status ?? 500, + err.response.status ?? 500 ); } } @@ -412,7 +412,7 @@ export class UsersController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: SWAGGER_DESC_UPDATE_USER_INFO, + description: SWAGGER_DESC_UPDATE_USER_INFO }) @ApiForbiddenResponse({ description: 'invalid credentials', @@ -421,17 +421,17 @@ export class UsersController { properties: { statusCode: { type: 'number' }, message: { type: 'string' }, - error: { type: 'string' }, - }, - }, + error: { type: 'string' } + } + } }) @ApiOkResponse({ - description: 'Returns updated user', + description: 'Returns updated user' }) async changeUserInfo( @Body() newData: UserDto, @Param('email') email: string, - @Req() req: FastifyRequest, + @Req() req: FastifyRequest ): Promise { try { const user = await this.usersService.findByEmail(email); @@ -445,7 +445,7 @@ export class UsersController { } catch (err) { throw new HttpException( err.message || 'Internal server error', - err.status || 500, + err.status || 500 ); } } @@ -455,7 +455,7 @@ export class UsersController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: SWAGGER_DESC_FIND_USER, + description: SWAGGER_DESC_FIND_USER }) @ApiForbiddenResponse({ description: 'invalid credentials', @@ -464,17 +464,17 @@ export class UsersController { properties: { statusCode: { type: 'number' }, message: { type: 'string' }, - error: { type: 'string' }, - }, - }, + error: { type: 'string' } + } + } }) @ApiNotFoundResponse() @ApiOkResponse({ - description: 'Returns user info', + description: 'Returns user info' }) async getUserInfo( @Param('email') email: string, - @Req() req: FastifyRequest, + @Req() req: FastifyRequest ): Promise { try { const user = await this.usersService.findByEmail(email); @@ -489,7 +489,7 @@ export class UsersController { } catch (err) { throw new HttpException( err.message || 'Internal server error', - err.status || 500, + err.status || 500 ); } } @@ -499,7 +499,7 @@ export class UsersController { @UseGuards(AuthGuard, AdminGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: SWAGGER_DESC_ADMIN_RIGHTS, + description: SWAGGER_DESC_ADMIN_RIGHTS }) @ApiForbiddenResponse({ description: 'user has no admin rights', @@ -507,12 +507,12 @@ export class UsersController { type: 'object', properties: { statusCode: { type: 'number' }, - message: { type: 'string' }, - }, - }, + message: { type: 'string' } + } + } }) @ApiOkResponse({ - description: 'Returns true if user has admin rights', + description: 'Returns true if user has admin rights' }) getAdminStatus(@Param('email') email: string): Promise { return this.usersService.getPermissions(email); @@ -523,10 +523,10 @@ export class UsersController { @UseGuards(AuthGuard) @JwtType(JwtProcessorType.RSA) @ApiOperation({ - description: SWAGGER_DESC_UPLOAD_USER_PHOTO, + description: SWAGGER_DESC_UPLOAD_USER_PHOTO }) @ApiOkResponse({ - description: 'Photo updated', + description: 'Photo updated' }) @UseInterceptors(AnyFilesInterceptor) async uploadFile(@Param('email') email: string, @Req() req: FastifyRequest) { @@ -540,11 +540,11 @@ export class UsersController { const xmlDoc = parseXml(xml, { noent: true, dtdvalid: true, - recover: true, + recover: true }); await this.usersService.updatePhoto( email, - Buffer.from(xmlDoc.toString(), 'utf8'), + Buffer.from(xmlDoc.toString(), 'utf8') ); return xmlDoc.toString(true); } else { @@ -553,7 +553,7 @@ export class UsersController { } catch (err) { throw new InternalServerErrorException({ error: err.message, - location: __filename, + location: __filename }); } } @@ -562,8 +562,8 @@ export class UsersController { return JSON.parse( Buffer.from( request.headers.authorization.split('.')[1], - 'base64', - ).toString(), + 'base64' + ).toString() ).user; } @@ -579,7 +579,7 @@ export class UsersController { } throw new HttpException( err.message ?? 'Something went wrong', - err.status ?? HttpStatus.INTERNAL_SERVER_ERROR, + err.status ?? HttpStatus.INTERNAL_SERVER_ERROR ); } } diff --git a/src/users/users.module.ts b/src/users/users.module.ts index ac2efb6b..42702e7e 100644 --- a/src/users/users.module.ts +++ b/src/users/users.module.ts @@ -11,6 +11,6 @@ import { UsersService } from './users.service'; imports: [OrmModule, KeyCloakModule, forwardRef(() => AuthModule)], controllers: [UsersController], providers: [UsersService, KeyCloakService, HttpClientService], - exports: [UsersService, KeyCloakService, HttpClientService], + exports: [UsersService, KeyCloakService, HttpClientService] }) export class UsersModule {} diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts index a23c80da..bc0f79d6 100644 --- a/src/users/users.service.spec.ts +++ b/src/users/users.service.spec.ts @@ -13,13 +13,13 @@ describe('UsersService', () => { UsersService, { provide: getRepositoryToken(User), - useValue: {}, + useValue: {} }, { provide: EntityManager, - useValue: {}, - }, - ], + useValue: {} + } + ] }).compile(); service = module.get(UsersService); diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 67d075b9..b476759a 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -2,7 +2,7 @@ import { EntityManager, EntityRepository, NotFoundError, - wrap, + wrap } from '@mikro-orm/core'; import { InjectRepository } from '@mikro-orm/nestjs'; import { Injectable, Logger, NotFoundException } from '@nestjs/common'; @@ -26,7 +26,7 @@ export class UsersService { constructor( @InjectRepository(User) private readonly usersRepository: EntityRepository, - private readonly em: EntityManager, + private readonly em: EntityManager ) {} async createUser(user: UserDto, isBasicUser = true): Promise { @@ -55,7 +55,7 @@ export class UsersService { throw new NotFoundError('Could not find user'); } wrap(user).assign({ - photo, + photo }); await this.em.persistAndFlush(user); @@ -78,7 +78,7 @@ export class UsersService { this.log.debug(`updateUserInfo ${oldUser.email}`); const newUser = oldUser; wrap(newUser).assign({ - ...newData, + ...newData }); await this.em.persistAndFlush(newUser); const poisonedUser = Object.create(newUser); @@ -88,7 +88,7 @@ export class UsersService { email: email, firstName: firstName, lastName: lastName, - ...poisonedUser.__proto__, + ...poisonedUser.__proto__ }; } @@ -114,9 +114,9 @@ export class UsersService { this.log.debug(`Called searchUsersByName`); return this.usersRepository.find( { - firstName: { $like: query + '%' }, + firstName: { $like: query + '%' } }, - limit ? { limit } : {}, + limit ? { limit } : {} ); } @@ -124,7 +124,7 @@ export class UsersService { const user = await this.usersRepository.findOne({ email }); return new PermissionDto({ - isAdmin: user.isAdmin, + isAdmin: user.isAdmin }); } diff --git a/src/utils/url.ts b/src/utils/url.ts index b5b583bd..66d32578 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -2,7 +2,7 @@ // VULNERABLE TO PROTOTYPE POLLUTION! const splitUriIntoParamsPPVulnerable = ( params, - coerce = undefined, + coerce = undefined ): Record => { if (params.charAt(0) === '?') { params = params.substring(1); diff --git a/test/auth.e2e-spec.ts b/test/auth.e2e-spec.ts index 7d24b5de..6a6bd9e7 100644 --- a/test/auth.e2e-spec.ts +++ b/test/auth.e2e-spec.ts @@ -8,8 +8,8 @@ const generateToken = async (jwtType) => { { user: 'admin', password: 'admin', - op: 'basic', - }, + op: 'basic' + } ); return headers.authorization; }; @@ -37,7 +37,7 @@ describe('/api', () => { .run({ method: 'GET', headers: { authorization: token }, - url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate`, + url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate` }); }); @@ -50,7 +50,7 @@ describe('/api', () => { .run({ method: 'GET', headers: { authorization: token }, - url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate`, + url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate` }); }); @@ -63,7 +63,7 @@ describe('/api', () => { .run({ method: 'GET', headers: { authorization: token }, - url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate`, + url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate` }); }); @@ -76,7 +76,7 @@ describe('/api', () => { .run({ method: 'GET', headers: { authorization: token }, - url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate`, + url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate` }); }); @@ -89,7 +89,7 @@ describe('/api', () => { .run({ method: 'GET', headers: { authorization: token }, - url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate`, + url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate` }); }); @@ -102,7 +102,7 @@ describe('/api', () => { .run({ method: 'GET', headers: { authorization: token }, - url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate`, + url: `${process.env.SEC_TESTER_TARGET}/api/auth/jwt/${jwtType}/validate` }); }); }); diff --git a/test/config.e2e-spec.ts b/test/config.e2e-spec.ts index d35ed53b..a57e4f06 100644 --- a/test/config.e2e-spec.ts +++ b/test/config.e2e-spec.ts @@ -19,12 +19,12 @@ describe('/api', () => { await runner .createScan({ tests: [TestType.COOKIE_SECURITY], - name: 'COOKIE_SECURITY', + name: 'COOKIE_SECURITY' }) .timeout(timeout) .run({ method: 'GET', - url: `${process.env.SEC_TESTER_TARGET}/api/config`, + url: `${process.env.SEC_TESTER_TARGET}/api/config` }); }); @@ -32,12 +32,12 @@ describe('/api', () => { await runner .createScan({ tests: [TestType.HEADER_SECURITY], - name: 'HEADER_SECURITY', + name: 'HEADER_SECURITY' }) .timeout(timeout) .run({ method: 'GET', - url: `${process.env.SEC_TESTER_TARGET}/api/config?query=no-sec-headers`, + url: `${process.env.SEC_TESTER_TARGET}/api/config?query=no-sec-headers` }); }); @@ -45,15 +45,15 @@ describe('/api', () => { await runner .createScan({ tests: [TestType.FULL_PATH_DISCLOSURE], - name: 'FULL_PATH_DISCLOSURE', + name: 'FULL_PATH_DISCLOSURE' }) .timeout(timeout) .run({ method: 'GET', headers: { - cookie: `bc-calls-counter=${Date.now().toString()}`, + cookie: `bc-calls-counter=${Date.now().toString()}` }, - url: `${process.env.SEC_TESTER_TARGET}/api/config`, + url: `${process.env.SEC_TESTER_TARGET}/api/config` }); }); }); diff --git a/test/jest-e2e.config.mjs b/test/jest-e2e.config.mjs index 11970ba9..8b2fcd63 100644 --- a/test/jest-e2e.config.mjs +++ b/test/jest-e2e.config.mjs @@ -3,5 +3,5 @@ import baseConfig from '../jest.config.json' assert { type: 'json' }; export default { ...baseConfig, testRegex: '.e2e-spec.ts$', - rootDir: '.', + rootDir: '.' }; diff --git a/test/metadata.e2e-spec.ts b/test/metadata.e2e-spec.ts index 2d2ec3d9..23ff932a 100644 --- a/test/metadata.e2e-spec.ts +++ b/test/metadata.e2e-spec.ts @@ -23,8 +23,8 @@ describe('/api', () => { method: 'POST', url: `${process.env.SEC_TESTER_TARGET}/api/metadata`, query: { - xml: '%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%3C%21DOCTYPE+child+%5B+%3C%21ENTITY+child+SYSTEM+%22file%3A%2F%2F%2Fetc%2Fpasswd%22%3E+%5D%3E%3Cchild%3E%3C%2Fchild%3E', - }, + xml: '%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%3C%21DOCTYPE+child+%5B+%3C%21ENTITY+child+SYSTEM+%22file%3A%2F%2F%2Fetc%2Fpasswd%22%3E+%5D%3E%3Cchild%3E%3C%2Fchild%3E' + } }); }); }); diff --git a/test/render.e2e-spec.ts b/test/render.e2e-spec.ts index 595a7224..9c7a7ffd 100644 --- a/test/render.e2e-spec.ts +++ b/test/render.e2e-spec.ts @@ -24,10 +24,10 @@ describe('/api', () => { headers: { Accept: 'application/json, text/plain, */*', 'Content-Type': 'text/plain', - Origin: process.env.SEC_TESTER_TARGET, + Origin: process.env.SEC_TESTER_TARGET }, body: `Some text`, - url: `${process.env.SEC_TESTER_TARGET}/api/render`, + url: `${process.env.SEC_TESTER_TARGET}/api/render` }); }); }); diff --git a/test/root.e2e-spec.ts b/test/root.e2e-spec.ts index 39658d29..c64356fa 100644 --- a/test/root.e2e-spec.ts +++ b/test/root.e2e-spec.ts @@ -21,7 +21,7 @@ describe('/', () => { .timeout(3000000) .run({ method: 'GET', - url: `${process.env.SEC_TESTER_TARGET}`, + url: `${process.env.SEC_TESTER_TARGET}` }); }); @@ -29,12 +29,12 @@ describe('/', () => { await runner .createScan({ tests: [TestType.INSECURE_TLS_CONFIGURATION], - name: 'INSECURE_TLS_CONFIGURATION', + name: 'INSECURE_TLS_CONFIGURATION' }) .timeout(timeout) .run({ method: 'GET', - url: `${process.env.SEC_TESTER_TARGET}`, + url: `${process.env.SEC_TESTER_TARGET}` }); }); }); diff --git a/test/spawn.e2e-spec.ts b/test/spawn.e2e-spec.ts index 4381bc4d..299c91d6 100644 --- a/test/spawn.e2e-spec.ts +++ b/test/spawn.e2e-spec.ts @@ -21,7 +21,7 @@ describe('/api', () => { .timeout(timeout) .run({ method: 'GET', - url: `${process.env.SEC_TESTER_TARGET}/api/spawn?command=pwd`, + url: `${process.env.SEC_TESTER_TARGET}/api/spawn?command=pwd` }); }); }); diff --git a/test/testimonials.e2e-spec.ts b/test/testimonials.e2e-spec.ts index 1cf61296..2524c44e 100644 --- a/test/testimonials.e2e-spec.ts +++ b/test/testimonials.e2e-spec.ts @@ -21,7 +21,7 @@ describe('/api', () => { .timeout(timeout) .run({ method: 'GET', - url: `${process.env.SEC_TESTER_TARGET}/api/testimonials/count?query=lorem`, + url: `${process.env.SEC_TESTER_TARGET}/api/testimonials/count?query=lorem` }); }); });