Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/admin/admin-audit.interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// @ts-nocheck

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, tap } from 'rxjs';
import { PrismaService } from '../database/prisma.service';
Expand Down
3 changes: 2 additions & 1 deletion src/admin/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
HttpStatus,
} from '@nestjs/common';
import { Response } from 'express';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { Roles } from '../auth/decorators/roles.decorator';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
Expand Down Expand Up @@ -48,6 +48,7 @@ import { ArchiveService } from '../archive/archive.service';
import { CleanupService } from '../database/cleanup.service';

@ApiTags('Admin')
@ApiBearerAuth('access-token')
@Controller('admin')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.ADMIN)
Expand Down
33 changes: 15 additions & 18 deletions src/admin/admin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ export class AdminService {
async listUsers(query: AdminUsersQueryDto) {
const page = query.page ?? 1;
const limit = query.limit ?? 20;
const skip = (query as any).cursor
? undefined
: (page - 1) * limit;
const skip = (query as any).cursor ? undefined : (page - 1) * limit;

const where: any = {
role: query.role,
Expand Down Expand Up @@ -148,9 +146,10 @@ export class AdminService {
this.prisma.user.count({ where }),
]);

const nextCursor = items.length === limit
? Buffer.from((items[items.length - 1] as any).createdAt.toISOString()).toString('base64')
: null;
const nextCursor =
items.length === limit
? Buffer.from((items[items.length - 1] as any).createdAt.toISOString()).toString('base64')
: null;

return { total, page, limit, items, nextCursor, previousCursor: (query as any).cursor || null };
}
Expand Down Expand Up @@ -241,9 +240,7 @@ export class AdminService {
async getModerationQueue(query: ModerationQueueQueryDto) {
const page = query.page ?? 1;
const limit = query.limit ?? 20;
const skip = (query as any).cursor
? undefined
: (page - 1) * limit;
const skip = (query as any).cursor ? undefined : (page - 1) * limit;

const where: any = {
status: query.status ?? PropertyStatus.PENDING,
Expand Down Expand Up @@ -273,9 +270,10 @@ export class AdminService {
this.prisma.property.count({ where }),
]);

const nextCursor = items.length === limit
? Buffer.from((items[items.length - 1] as any).createdAt.toISOString()).toString('base64')
: null;
const nextCursor =
items.length === limit
? Buffer.from((items[items.length - 1] as any).createdAt.toISOString()).toString('base64')
: null;

return { total, page, limit, items, nextCursor, previousCursor: (query as any).cursor || null };
}
Expand Down Expand Up @@ -350,9 +348,7 @@ export class AdminService {
async monitorTransactions(query: TransactionMonitoringQueryDto) {
const page = query.page ?? 1;
const limit = query.limit ?? 20;
const skip = (query as any).cursor
? undefined
: (page - 1) * limit;
const skip = (query as any).cursor ? undefined : (page - 1) * limit;

const where: any = {
status: query.status,
Expand Down Expand Up @@ -385,9 +381,10 @@ export class AdminService {
this.prisma.transaction.count({ where }),
]);

const nextCursor = items.length === limit
? Buffer.from((items[items.length - 1] as any).createdAt.toISOString()).toString('base64')
: null;
const nextCursor =
items.length === limit
? Buffer.from((items[items.length - 1] as any).createdAt.toISOString()).toString('base64')
: null;

return { total, page, limit, items, nextCursor, previousCursor: (query as any).cursor || null };
}
Expand Down
16 changes: 16 additions & 0 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @ts-nocheck

import { Body, Controller, Get, Param, Patch, Post, Req, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { AuthService } from './auth.service';
import { ApiKeyAnalyticsService } from './api-key-analytics.service';
import {
Expand Down Expand Up @@ -28,6 +29,7 @@ import { UserRole } from '../types/prisma.types';
import { Request } from 'express';
import { VerifyEmailDto } from '../users/dto/email-change.dto';

@ApiTags('Authentication')
@Controller('auth')
export class AuthController {
constructor(
Expand Down Expand Up @@ -67,6 +69,7 @@ export class AuthController {
return this.authService.refreshToken(refreshTokenDto, ipAddress, userAgent);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('logout')
logout(
Expand All @@ -77,18 +80,21 @@ export class AuthController {
return this.authService.logout(user, logoutDto.refreshToken, request.accessToken);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('logout-all')
logoutAllDevices(@CurrentUser() user: AuthUserPayload, @Req() request: { accessToken?: string }) {
return this.authService.logoutAllDevices(user, request.accessToken);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Get('me')
me(@CurrentUser() user: AuthUserPayload) {
return this.authService.me(user);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('change-password')
changePassword(
Expand All @@ -98,12 +104,14 @@ export class AuthController {
return this.authService.changePassword(user, changePasswordDto);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('2fa/setup')
setupTwoFactor(@CurrentUser() user: AuthUserPayload) {
return this.authService.setupTwoFactor(user);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('2fa/verify')
verifyTwoFactor(
Expand All @@ -113,6 +121,7 @@ export class AuthController {
return this.authService.verifyTwoFactor(user, verifyTwoFactorDto);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('2fa/disable')
disableTwoFactor(
Expand All @@ -133,30 +142,35 @@ export class AuthController {
};
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('api-keys')
createApiKey(@CurrentUser() user: AuthUserPayload, @Body() createApiKeyDto: CreateApiKeyDto) {
return this.authService.createApiKey(user, createApiKeyDto);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Get('api-keys')
listApiKeys(@CurrentUser() user: AuthUserPayload) {
return this.authService.listApiKeys(user);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('api-keys/:id/rotate')
rotateApiKey(@CurrentUser() user: AuthUserPayload, @Param('id') id: string) {
return this.authService.rotateApiKey(user, id);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post('api-keys/:id/revoke')
revokeApiKey(@CurrentUser() user: AuthUserPayload, @Param('id') id: string) {
return this.authService.revokeApiKey(user, id);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Patch('api-keys/:id/permissions')
updateApiKeyPermissions(
Expand All @@ -167,6 +181,7 @@ export class AuthController {
return this.authService.updateApiKeyPermissions(user, id, updateApiKeyPermissionsDto);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Get('api-keys/:id/usage')
getApiKeyUsage(@CurrentUser() user: AuthUserPayload, @Param('id') id: string) {
Expand All @@ -183,6 +198,7 @@ export class AuthController {
return this.authService.resetPassword(resetPasswordDto);
}

@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.ADMIN)
@Post('unlock-account')
Expand Down
16 changes: 12 additions & 4 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,9 @@ export class AuthService {
});
} catch (error: unknown) {
// Token might already be expired or invalid, continue with logout
this.logger.warn(`Failed to blacklist access token for user ${user.sub}: ${(error as Error).message}`);
this.logger.warn(
`Failed to blacklist access token for user ${user.sub}: ${(error as Error).message}`,
);
}
}

Expand Down Expand Up @@ -610,7 +612,9 @@ export class AuthService {
userId: user.sub,
});
} catch (error: unknown) {
this.logger.warn(`Failed to blacklist access token for user ${user.sub}: ${(error as Error).message}`);
this.logger.warn(
`Failed to blacklist access token for user ${user.sub}: ${(error as Error).message}`,
);
}
}

Expand Down Expand Up @@ -1621,12 +1625,16 @@ export class AuthService {
const bypass = this.configService.get<string>('CAPTCHA_BYPASS') === 'true';

if (bypass) {
this.logger.warn('CAPTCHA bypass is enabled via CAPTCHA_BYPASS=true. This should only be used in development.');
this.logger.warn(
'CAPTCHA bypass is enabled via CAPTCHA_BYPASS=true. This should only be used in development.',
);
return true;
}

if (!secret) {
throw new Error('RECAPTCHA_SECRET is not configured. Set CAPTCHA_BYPASS=true for development environments.');
throw new Error(
'RECAPTCHA_SECRET is not configured. Set CAPTCHA_BYPASS=true for development environments.',
);
}

try {
Expand Down
5 changes: 1 addition & 4 deletions src/blockchain/blockchain.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,7 @@ export class BlockchainService {
throw error;
}
const err = error as Error;
this.logger.error(
`Failed to record transaction on blockchain: ${err.message}`,
err.stack,
);
this.logger.error(`Failed to record transaction on blockchain: ${err.message}`, err.stack);
throw new InternalServerErrorException('Failed to record transaction on blockchain');
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/blockchain/service/blockchain-recording.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export class BlockchainRecordingProcessor {
// Use recordTransactionOnBlockchain with minimal required data
// The full recording should be initiated by the controller with complete data
// For queue processing, we just log and mark as processed
this.logger.log(`Blockchain recording job ${job.id} processed for transaction ${job.data.transactionId}`);
this.logger.log(
`Blockchain recording job ${job.id} processed for transaction ${job.data.transactionId}`,
);
return { processed: true, transactionId: job.data.transactionId };
}
}
3 changes: 3 additions & 0 deletions src/dashboard/dashboard.controller.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// @ts-nocheck

import { Controller, Get, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { DashboardService } from './dashboard.service';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { AuthUserPayload } from '../auth/types/auth-user.type';
import { DashboardDto } from './dto/dashboard.dto';

@ApiTags('Dashboard')
@ApiBearerAuth('access-token')
@Controller('dashboard')
@UseGuards(JwtAuthGuard)
export class DashboardController {
Expand Down
4 changes: 3 additions & 1 deletion src/documents/documents.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
UseGuards,
HttpStatus,
} from '@nestjs/common';
import { ApiOperation, ApiBody, ApiResponse } from '@nestjs/swagger';
import { ApiOperation, ApiBody, ApiResponse, ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { Response } from 'express';
import { DocumentsService } from './documents.service';
import {
Expand All @@ -30,6 +30,8 @@ import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { AuthUserPayload } from '../auth/types/auth-user.type';
import { UserRole } from '../types/prisma.types';

@ApiTags('Documents')
@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Controller('documents')
export class DocumentsController {
Expand Down
7 changes: 7 additions & 0 deletions src/favorites/favorites.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@ import {
Query,
UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { FavoritesService } from './favorites.service';
import { ListFavoritesQueryDto } from './dto/favorite.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { AuthUserPayload } from '../auth/types/auth-user.type';

@ApiTags('Favorites')
@Controller('favorites')
export class FavoritesController {
constructor(private readonly favoritesService: FavoritesService) {}

/**
* Add a property to the current user's favorites.
*/
@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Post(':propertyId')
add(
Expand All @@ -33,6 +36,7 @@ export class FavoritesController {
/**
* Remove a property from the current user's favorites.
*/
@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Delete(':propertyId')
remove(
Expand All @@ -45,6 +49,7 @@ export class FavoritesController {
/**
* List the current user's favorites (paginated).
*/
@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Get()
list(@CurrentUser() user: AuthUserPayload, @Query() query: ListFavoritesQueryDto) {
Expand All @@ -57,6 +62,7 @@ export class FavoritesController {
/**
* Total count of favorites for the current user.
*/
@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Get('count')
async myCount(@CurrentUser() user: AuthUserPayload) {
Expand All @@ -67,6 +73,7 @@ export class FavoritesController {
/**
* Whether a property is currently favorited by the user.
*/
@ApiBearerAuth('access-token')
@UseGuards(JwtAuthGuard)
@Get(':propertyId/status')
async status(
Expand Down
Loading
Loading