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
11 changes: 11 additions & 0 deletions harvest-finance/backend/src/auth/auth.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
Expand Down Expand Up @@ -37,6 +38,7 @@ describe('AuthController', () => {
logout: jest.fn(),
forgotPassword: jest.fn(),
resetPassword: jest.fn(),
generateTokens: jest.fn(),
};

mockStellarStrategy = {
Expand All @@ -47,6 +49,7 @@ describe('AuthController', () => {
.mockReturnValue(
'GD5DJQDQKG6GSUWQJQGQKQ5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q5Q',
),
networkPassphrase: 'Test SDF Network ; September 2015',
};

const module: TestingModule = await Test.createTestingModule({
Expand All @@ -60,6 +63,14 @@ describe('AuthController', () => {
provide: StellarStrategy,
useValue: mockStellarStrategy,
},
{
provide: CACHE_MANAGER,
useValue: {
get: jest.fn(),
set: jest.fn(),
del: jest.fn(),
},
},
],
}).compile();

Expand Down
5 changes: 3 additions & 2 deletions harvest-finance/backend/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { LoginDto } from './dto/login.dto';
import { RefreshTokenDto } from './dto/refresh-token.dto';
import { ForgotPasswordDto } from './dto/forgot-password.dto';
import { ResetPasswordDto } from './dto/reset-password.dto';
import { AuthResponseDto, TokenResponseDto } from './dto/auth-response.dto';
import { AuthResponseDto, LogoutResponseDto, TokenResponseDto } from './dto/auth-response.dto';
import { JwtAuthGuard } from './guards/jwt-auth.guard';
import { RateLimit } from '../common/decorators/rate-limit.decorator';
import { RateLimitGuard } from '../common/guards/rate-limit.guard';
Expand Down Expand Up @@ -124,10 +124,11 @@ export class AuthController {
@ApiResponse({
status: 200,
description: 'Logged out successfully',
type: LogoutResponseDto,
})
async logout(
@Req() req: Request,
): Promise<{ success: boolean; message: string }> {
): Promise<LogoutResponseDto> {
const token = (req as any).headers.authorization?.replace('Bearer ', '');
return this.authService.logout(token);
}
Expand Down
21 changes: 15 additions & 6 deletions harvest-finance/backend/src/auth/strategies/stellar.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,13 @@ import {
BadRequestException,
} from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy as PassportStrategyBase } from 'passport-strategy';
import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import * as StellarSdk from '@stellar/stellar-sdk';
import { User, UserRole } from '../../database/entities/user.entity';

// Minimal placeholder strategy class for PassportStrategy
class StellarPlaceholderStrategy {
authenticate() {}
}

export interface StellarPayload {
stellar_address: string;
iat?: number;
Expand All @@ -23,9 +19,22 @@ export interface StellarPayload {

@Injectable()
export class StellarStrategy extends PassportStrategy(
StellarPlaceholderStrategy,
PassportStrategyBase,
'stellar',
) {
authenticate(req: any, options?: any): void {
const transactionXdr =
req.body?.transaction || req.query?.transaction || req.headers?.transaction;

if (!transactionXdr) {
return this.fail('Missing Stellar transaction', 400);
}

this.validate(transactionXdr)
.then((user) => this.success(user))
.catch((err) => this.fail(err, 401));
}

private readonly serverKeypair: StellarSdk.Keypair;
private readonly networkPassphrase: string;
private readonly challengeTimeout: number = 300; // 5 minutes
Expand Down
12 changes: 10 additions & 2 deletions harvest-finance/backend/src/orders/dto/create-order.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IsString, IsNumber, Min, IsIn } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNumber, Min, IsIn, IsOptional } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

const SUPPORTED_CROPS = ['WHEAT', 'MAIZE', 'RICE', 'SOY'];

Expand All @@ -18,4 +18,12 @@ export class CreateOrderDto {
@IsNumber()
@Min(0.0000001)
price: number;

@ApiPropertyOptional({
example: 'XLM',
description: 'Asset code for payment, defaults to XLM',
})
@IsOptional()
@IsString()
assetCode?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export class OrderEntity {
cropType: string;
quantity: number;
price: number;
assetCode?: string;
status: OrderStatus;
createdAt: Date;
updatedAt: Date;
Expand Down
3 changes: 2 additions & 1 deletion harvest-finance/backend/src/orders/orders.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class OrdersService {
cropType: dto.cropType,
quantity: dto.quantity,
price: dto.price,
assetCode: dto.assetCode ?? 'XLM',
});
return order;
}
Expand Down Expand Up @@ -89,7 +90,7 @@ export class OrdersService {
orderId,
farmerPublicKey,
amount: upfrontAmount,
assetCode: 'XLM', // TODO: support other assets if needed
assetCode: order.assetCode ?? 'XLM',
});
// Update order status and record tx
order.status = OrderStatus.ACCEPTED;
Expand Down
Loading