Skip to content
Open
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
4 changes: 2 additions & 2 deletions src/admin/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import { SuspendCampaignDto } from './dtos/suspend-campaign.dto';
import { Roles } from '../common/decorators/roles.decorator';
import { RolesGuard } from '../common/guards/roles.guard';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';

@Controller('admin')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Roles('ADMIN')
export class AdminController {
constructor(private readonly adminService: AdminService) {}

Expand All @@ -29,8 +29,8 @@
return this.adminService.suspendCampaign(
id,
dto,
req.user.sub,

Check warning on line 32 in src/admin/admin.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .user on an `any` value

Check warning on line 32 in src/admin/admin.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe argument of type `any` assigned to a parameter of type `string`
req.user.email,

Check warning on line 33 in src/admin/admin.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .user on an `any` value

Check warning on line 33 in src/admin/admin.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe argument of type `any` assigned to a parameter of type `string`
);
}
}
2 changes: 1 addition & 1 deletion src/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AuthModule } from '../auth/auth.module';
import { AdminService } from './admin.service';
import { AdminController } from './admin.controller';
import { NotificationsModule } from '../notifications/notifications.module';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import { RolesGuard } from '../common/guards/roles.guard';

/** Module providing admin campaign suspension, user moderation, and audit logging */
Expand Down
2 changes: 1 addition & 1 deletion src/api-keys/api-keys.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { randomBytes, createHash } from 'crypto';
import { Request } from 'express';
import { PrismaService } from '../prisma/prisma.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import { Throttle } from '@nestjs/throttler';

interface JwtUser {
Expand Down
2 changes: 1 addition & 1 deletion src/api-keys/api-keys.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PrismaModule } from '../prisma/prisma.module';
import { AuthModule } from '../auth/auth.module';
import { ApiKeysController } from './api-keys.controller';
import { ApiKeyGuard } from './api-key.guard';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';

/** Provides API key generation, revocation, and authentication middleware */
@Module({
Expand Down
2 changes: 1 addition & 1 deletion src/auth/auth-logout.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
} from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import type { Cache } from 'cache-manager';
import { JwtAuthGuard } from './jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import {
ApiTags,
ApiOperation,
Expand Down Expand Up @@ -39,13 +39,13 @@
description: 'Invalid token',
})
async logout(@Req() req: Request): Promise<void> {
const user = req['user'];

Check warning on line 42 in src/auth/auth-logout.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe assignment of an error typed value

if (!user) {
throw new UnauthorizedException('Invalid token');
}

const walletAddress = user.walletAddress;

Check warning on line 48 in src/auth/auth-logout.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .walletAddress on a type that cannot be resolved

Check warning on line 48 in src/auth/auth-logout.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe assignment of an error typed value
if (walletAddress) {
await this.cacheManager.del(`refresh:${walletAddress}`);
}
Expand Down
46 changes: 0 additions & 46 deletions src/auth/jwt-auth.guard.ts

This file was deleted.

30 changes: 0 additions & 30 deletions src/auth/jwt.strategy.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/campaigns/campaigns.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import { UpdateCampaignDto } from './dto/update-campaign.dto';
import { CreateCampaignDto } from './dto/create-campaign.dto';
import { Request } from 'express';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import { AdminGuard } from '../users/guards/admin.guard';
import {
BrowseCampaignsQueryDto,
Expand Down Expand Up @@ -69,7 +69,7 @@
@Body() body: CreateCampaignDto,
@Req() req: Request & { user: any },
) {
const userId = req.user?.sub as string;

Check warning on line 72 in src/campaigns/campaigns.controller.ts

View workflow job for this annotation

GitHub Actions / Lint

Unsafe member access .sub on an `any` value
return this.campaignsService.createCampaign(userId, body);
}

Expand Down
2 changes: 1 addition & 1 deletion src/campaigns/campaigns.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CampaignsService } from './campaigns.service';
import { PrismaModule } from '../prisma/prisma.module';
import { AuthModule } from '../auth/auth.module';
import { StellarModule } from '../stellar/stellar.module';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import { AdminGuard } from '../users/guards/admin.guard';
import { DonationsModule } from '../donations/donations.module';

Expand Down
4 changes: 2 additions & 2 deletions src/campaigns/campaigns.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('CampaignsService milestone target validation', () => {
};

it.each([
['missing', undefined],
['missing', undefined as string | undefined],
['zero', '0'],
['zero decimal', '0.0000000'],
['below the minimum precision', '0.00000001'],
Expand All @@ -34,7 +34,7 @@ describe('CampaignsService milestone target validation', () => {
milestones: [
{
title: 'Prototype',
targetAmount,
targetAmount: targetAmount as string,
},
],
}),
Expand Down
2 changes: 1 addition & 1 deletion src/donations/donations.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
Req,
Request,
} from '@nestjs/common';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import { DonationsService } from './donations.service';
import { CreateDonationDto } from './dto/create-donation.dto';
import {
Expand Down
2 changes: 1 addition & 1 deletion src/donations/donations.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Module, forwardRef } from '@nestjs/common';
import { AuthModule } from '../auth/auth.module';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import { CampaignsModule } from '../campaigns/campaigns.module';
import { PrismaModule } from '../prisma/prisma.module';
import { StellarModule } from '../stellar/stellar.module';
Expand Down
2 changes: 1 addition & 1 deletion src/notifications/notifications.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
UseGuards,
} from '@nestjs/common';
import { Request } from 'express';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { JwtAuthGuard } from '../users/guards/jwt-auth.guard';
import { NotificationsService } from './notifications.service';

@Controller('notifications')
Expand Down
35 changes: 26 additions & 9 deletions src/users/guards/jwt-auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,46 @@ import {
UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { Request } from 'express';

/**
* Validates JWT from the Authorization header and attaches the decoded
* payload to `request.user`. The secret is read from config so this
* guard is not tied to a specific JwtModule registration.
*/
@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private readonly jwtService: JwtService) {}
constructor(
private readonly jwt: JwtService,
private readonly config: ConfigService,
) {}

canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
const authHeader = request.headers.authorization;
const request = context
.switchToHttp()
.getRequest<Request & { user: unknown }>();
const authHeader = request.headers['authorization'];

if (!authHeader || !authHeader.startsWith('Bearer ')) {
if (!authHeader?.startsWith('Bearer ')) {
throw new UnauthorizedException(
'Missing or invalid authorization header',
'Missing or invalid Authorization header',
);
}

const token = authHeader.substring(7);
const token = authHeader.slice(7);

try {
const payload = this.jwtService.verify(token);
const payload = this.jwt.verify(token, {
secret: this.config.get<string>(
'JWT_SECRET',
'orbitchain-default-secret',
),
}) as Record<string, unknown>;
request.user = payload;
return true;
} catch (error) {
throw new UnauthorizedException('Invalid token');
} catch {
throw new UnauthorizedException('Invalid or expired token');
}
}
}
Loading