Normalize quote usage in imports

Standardized the quote style to double quotes across all TypeScript files for consistency. This includes ".ts" and ".dto" files.
This commit is contained in:
Mathis H (Avnyr) 2024-11-12 13:37:29 +01:00
parent 2fdc16e003
commit 8ea217fe9f
Signed by: Mathis
GPG Key ID: DD9E0666A747D126
52 changed files with 1475 additions and 1486 deletions

View File

@ -1,22 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Test, TestingModule } from "@nestjs/testing";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
describe('AppController', () => {
let appController: AppController;
describe("AppController", () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
describe("root", () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe("Hello World!");
});
});
});

View File

@ -1,12 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { Controller, Get } from "@nestjs/common";
import { AppService } from "./app.service";
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return 'Hello';
}
@Get()
getHello(): string {
return "Hello";
}
}

View File

@ -1,38 +1,38 @@
import { Module } from '@nestjs/common';
import { AppController } from '@/app.controller';
import { AppService } from '@/app.service';
import { ConfigModule } from '@nestjs/config';
import { AuthModule } from '@/auth/auth.module';
import { PrismaModule } from '@/prisma/prisma.module';
import { RoleModule } from '@/role/role.module';
import { PromoCodeModule } from '@/promoCode/promoCode.module';
import { CryptoModule } from '@/crypto/crypto.module';
import { TradeModule } from '@/trade/trade.module';
import { OfferModule } from '@/offer/offer.module';
import { UserModule } from '@/user/user.module';
import { ThrottlerModule } from '@nestjs/throttler';
import { AppController } from "@/app.controller";
import { AppService } from "@/app.service";
import { AuthModule } from "@/auth/auth.module";
import { CryptoModule } from "@/crypto/crypto.module";
import { OfferModule } from "@/offer/offer.module";
import { PrismaModule } from "@/prisma/prisma.module";
import { PromoCodeModule } from "@/promoCode/promoCode.module";
import { RoleModule } from "@/role/role.module";
import { TradeModule } from "@/trade/trade.module";
import { UserModule } from "@/user/user.module";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { ThrottlerModule } from "@nestjs/throttler";
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
AuthModule,
PrismaModule,
RoleModule,
PromoCodeModule,
CryptoModule,
TradeModule,
OfferModule,
UserModule,
ThrottlerModule.forRoot([
{
ttl: 60000,
limit: 40,
},
]),
],
controllers: [AppController],
providers: [AppService],
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
AuthModule,
PrismaModule,
RoleModule,
PromoCodeModule,
CryptoModule,
TradeModule,
OfferModule,
UserModule,
ThrottlerModule.forRoot([
{
ttl: 60000,
limit: 40,
},
]),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

View File

@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { Injectable } from "@nestjs/common";
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
getHello(): string {
return "Hello World!";
}
}

View File

@ -1,21 +1,21 @@
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthLoginDto, AuthRegisterDto } from './dto';
import { ApiTags } from '@nestjs/swagger';
import { Body, Controller, HttpCode, HttpStatus, Post } from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { AuthService } from "./auth.service";
import { AuthLoginDto, AuthRegisterDto } from "./dto";
@ApiTags('auth')
@Controller('auth')
@ApiTags("auth")
@Controller("auth")
export class AuthController {
constructor(private authService: AuthService) {}
constructor(private authService: AuthService) {}
@Post('sign-up')
signUp(@Body() dto: AuthRegisterDto) {
return this.authService.signup(dto);
}
@Post("sign-up")
signUp(@Body() dto: AuthRegisterDto) {
return this.authService.signup(dto);
}
@HttpCode(HttpStatus.OK)
@Post('sign-in')
signIn(@Body() dto: AuthLoginDto) {
return this.authService.signin(dto);
}
@HttpCode(HttpStatus.OK)
@Post("sign-in")
signIn(@Body() dto: AuthLoginDto) {
return this.authService.signin(dto);
}
}

View File

@ -1,12 +1,12 @@
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtStrategy } from './strategy';
import { Module } from "@nestjs/common";
import { JwtModule } from "@nestjs/jwt";
import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";
import { JwtStrategy } from "./strategy";
@Module({
imports: [JwtModule.register({})],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
imports: [JwtModule.register({})],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
})
export class AuthModule {}

View File

@ -1,108 +1,113 @@
import { ForbiddenException, Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { AuthLoginDto, AuthRegisterDto } from './dto';
import * as argon from 'argon2';
import { Prisma, User } from '@prisma/client';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { ForbiddenException, Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { JwtService } from "@nestjs/jwt";
import { Prisma, User } from "@prisma/client";
import * as argon from "argon2";
import { PrismaService } from "../prisma/prisma.service";
import { AuthLoginDto, AuthRegisterDto } from "./dto";
@Injectable()
export class AuthService {
private readonly initialBalance = 1000;
private readonly initialBalance = 1000;
constructor(
private prisma: PrismaService,
private jwt: JwtService,
private config: ConfigService,
) {}
constructor(
private prisma: PrismaService,
private jwt: JwtService,
private config: ConfigService,
) {}
async signup(dto: AuthRegisterDto) {
const hash = await argon.hash(dto.password);
const promoCode = await this.getPromoCode(dto.promoCode);
const userRole = await this.getUserRole('user');
const balance = this.calculateBalance(promoCode);
async signup(dto: AuthRegisterDto) {
const hash = await argon.hash(dto.password);
const promoCode = await this.getPromoCode(dto.promoCode);
const userRole = await this.getUserRole("user");
const balance = this.calculateBalance(promoCode);
try {
const user = await this.createUser(dto, hash, userRole.id, balance);
return this.signToken(user);
} catch (error) {
this.handleSignupError(error);
}
}
try {
const user = await this.createUser(dto, hash, userRole.id, balance);
return this.signToken(user);
} catch (error) {
this.handleSignupError(error);
}
}
private async getPromoCode(promoCode: string) {
return this.prisma.promoCode.findFirst({
where: {name: promoCode},
});
}
private async getPromoCode(promoCode: string) {
return this.prisma.promoCode.findFirst({
where: { name: promoCode },
});
}
private async getUserRole(roleName: string) {
return this.prisma.role.findFirst({
where: {name: roleName},
});
}
private async getUserRole(roleName: string) {
return this.prisma.role.findFirst({
where: { name: roleName },
});
}
private calculateBalance(promoCode: any) {
let balance = this.initialBalance;
if (promoCode && promoCode.value) {
balance += promoCode.value;
}
return balance;
}
private calculateBalance(promoCode: any) {
let balance = this.initialBalance;
if (promoCode && promoCode.value) {
balance += promoCode.value;
}
return balance;
}
private async createUser(dto: AuthRegisterDto, hash: string, roleId: string, balance: number) {
return this.prisma.user.create({
data: {
firstName: dto.firstName,
lastName: dto.lastName,
pseudo: dto.pseudo,
email: dto.email,
hash,
roleId,
isActive: true,
dollarAvailables: balance,
},
});
}
private async createUser(
dto: AuthRegisterDto,
hash: string,
roleId: string,
balance: number,
) {
return this.prisma.user.create({
data: {
firstName: dto.firstName,
lastName: dto.lastName,
pseudo: dto.pseudo,
email: dto.email,
hash,
roleId,
isActive: true,
dollarAvailables: balance,
},
});
}
private handleSignupError(error: any) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
if (error.code === 'P2002') {
throw new ForbiddenException('Credentials taken');
}
}
throw error;
}
private handleSignupError(error: any) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
if (error.code === "P2002") {
throw new ForbiddenException("Credentials taken");
}
}
throw error;
}
async signin(dto: AuthLoginDto) {
const userDatas = await this.prisma.user.findUnique({
where: { email: dto.email },
include: {
UserHasCrypto: { include: { Crypto: true } },
Role: true,
},
});
async signin(dto: AuthLoginDto) {
const userDatas = await this.prisma.user.findUnique({
where: { email: dto.email },
include: {
UserHasCrypto: { include: { Crypto: true } },
Role: true,
},
});
if (!userDatas) throw new ForbiddenException('Credentials incorrect');
if (!userDatas) throw new ForbiddenException("Credentials incorrect");
const pwMatches = await argon.verify(userDatas.hash, dto.password);
if (!pwMatches) throw new ForbiddenException('Credentials incorrect');
const pwMatches = await argon.verify(userDatas.hash, dto.password);
if (!pwMatches) throw new ForbiddenException("Credentials incorrect");
return this.signToken(userDatas);
}
return this.signToken(userDatas);
}
async signToken(user: any): Promise<{ access_token: string; user: User }> {
const payload = { sub: user.id, email: user.email };
user.hash = null;
const secret = this.config.get('JWT_SECRET');
const token = await this.jwt.signAsync(payload, {
expiresIn: '30d',
secret: secret,
});
async signToken(user: any): Promise<{ access_token: string; user: User }> {
const payload = { sub: user.id, email: user.email };
user.hash = null;
const secret = this.config.get("JWT_SECRET");
const token = await this.jwt.signAsync(payload, {
expiresIn: "30d",
secret: secret,
});
return {
access_token: token,
user,
};
}
return {
access_token: token,
user,
};
}
}

View File

@ -1,11 +1,11 @@
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { ExecutionContext, createParamDecorator } from "@nestjs/common";
export const GetUser = createParamDecorator(
(data: string | undefined, ctx: ExecutionContext) => {
const request: Express.Request = ctx.switchToHttp().getRequest();
if (data) {
return request.user[data];
}
return request.user;
},
(data: string | undefined, ctx: ExecutionContext) => {
const request: Express.Request = ctx.switchToHttp().getRequest();
if (data) {
return request.user[data];
}
return request.user;
},
);

View File

@ -1 +1 @@
export * from './get-user.decorator';
export * from "./get-user.decorator";

View File

@ -1,13 +1,13 @@
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
import { IsEmail, IsNotEmpty, IsString } from "class-validator";
export class AuthLoginDto {
@IsEmail()
@IsNotEmpty()
@ApiProperty({ type: String, description: 'email' })
email: string;
@IsEmail()
@IsNotEmpty()
@ApiProperty({ type: String, description: "email" })
email: string;
@ApiProperty({ type: String, description: 'password' })
@IsString()
@IsNotEmpty()
password: string;
@ApiProperty({ type: String, description: "password" })
@IsString()
@IsNotEmpty()
password: string;
}

View File

@ -1,73 +1,73 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
import {
IsEmail,
IsInt,
IsNotEmpty,
IsOptional,
IsString,
Max,
MaxLength,
Min,
MinLength,
} from 'class-validator';
IsEmail,
IsInt,
IsNotEmpty,
IsOptional,
IsString,
Max,
MaxLength,
Min,
MinLength,
} from "class-validator";
export class AuthRegisterDto {
@ApiProperty({
type: String,
description: 'FirstName',
example: 'Thomas',
})
@MinLength(1)
@MaxLength(50)
@IsNotEmpty()
@IsString()
firstName: string;
@ApiProperty({
type: String,
description: "FirstName",
example: "Thomas",
})
@MinLength(1)
@MaxLength(50)
@IsNotEmpty()
@IsString()
firstName: string;
@ApiProperty({
type: String,
description: 'Last Name',
example: 'Anderson',
})
@MinLength(1)
@MaxLength(50)
@IsNotEmpty()
@IsString()
lastName: string;
@ApiProperty({
type: String,
description: "Last Name",
example: "Anderson",
})
@MinLength(1)
@MaxLength(50)
@IsNotEmpty()
@IsString()
lastName: string;
@ApiProperty({
type: String,
description: 'Pseudo',
example: 'Néo',
})
@MinLength(1)
@MaxLength(50)
@IsNotEmpty()
@IsString()
pseudo: string;
@ApiProperty({
type: String,
description: "Pseudo",
example: "Néo",
})
@MinLength(1)
@MaxLength(50)
@IsNotEmpty()
@IsString()
pseudo: string;
@ApiProperty({
type: String,
description: 'email',
example: 'neo@matrix.fr',
})
@MaxLength(255)
@IsEmail()
@IsNotEmpty()
email: string;
@ApiProperty({
type: String,
description: "email",
example: "neo@matrix.fr",
})
@MaxLength(255)
@IsEmail()
@IsNotEmpty()
email: string;
@ApiProperty({
type: String,
description: 'password',
example: 'AAaa11&&&&',
})
@IsString()
@IsNotEmpty()
password: string;
@ApiProperty({
type: String,
description: "password",
example: "AAaa11&&&&",
})
@IsString()
@IsNotEmpty()
password: string;
@ApiProperty({
type: String,
description: 'promoCode',
example: 'FILOU20',
})
@IsOptional()
promoCode: string;
@ApiProperty({
type: String,
description: "promoCode",
example: "FILOU20",
})
@IsOptional()
promoCode: string;
}

View File

@ -1,2 +1,2 @@
export * from './auth.register.dto';
export * from './auth.login.dto';
export * from "./auth.register.dto";
export * from "./auth.login.dto";

View File

@ -1 +1 @@
export * from './jwt.guard';
export * from "./jwt.guard";

View File

@ -1,7 +1,7 @@
import { AuthGuard } from '@nestjs/passport';
import { AuthGuard } from "@nestjs/passport";
export class JwtGuard extends AuthGuard('jwt') {
constructor() {
super();
}
export class JwtGuard extends AuthGuard("jwt") {
constructor() {
super();
}
}

View File

@ -1 +1 @@
export * from './jwt.strategy';
export * from "./jwt.strategy";

View File

@ -1,28 +1,28 @@
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PrismaService } from "@/prisma/prisma.service";
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { PassportStrategy } from "@nestjs/passport";
import { ExtractJwt, Strategy } from "passport-jwt";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(
config: ConfigService,
private prisma: PrismaService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: config.get('JWT_SECRET'),
});
}
export class JwtStrategy extends PassportStrategy(Strategy, "jwt") {
constructor(
config: ConfigService,
private prisma: PrismaService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: config.get("JWT_SECRET"),
});
}
async validate(payload: { sub: string; email: string }) {
const user = await this.prisma.user.findUnique({
where: {
id: payload.sub,
},
});
delete user.hash;
return user;
}
async validate(payload: { sub: string; email: string }) {
const user = await this.prisma.user.findUnique({
where: {
id: payload.sub,
},
});
delete user.hash;
return user;
}
}

View File

@ -1,73 +1,73 @@
import {
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
} from '@nestjs/common';
import { GetUser } from '../auth/decorator';
import { ApiTags } from '@nestjs/swagger';
import { User } from '@prisma/client';
import { CryptoService } from './crypto.service';
import { CryptoDto } from './dto';
import { JwtGuard } from 'src/auth/guard';
import { BuyCryptoDto } from './dto/buy.crypto.dto';
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
} from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { User } from "@prisma/client";
import { JwtGuard } from "src/auth/guard";
import { GetUser } from "../auth/decorator";
import { CryptoService } from "./crypto.service";
import { CryptoDto } from "./dto";
import { BuyCryptoDto } from "./dto/buy.crypto.dto";
@UseGuards(JwtGuard)
@ApiTags('crypto')
@Controller('crypto')
@ApiTags("crypto")
@Controller("crypto")
export class CryptoController {
constructor(private cryptoService: CryptoService) {}
constructor(private cryptoService: CryptoService) {}
@Get('/all')
getAllPromoCodes(@GetUser() user: User) {
return this.cryptoService.getCryptos(user.id);
}
@Get('/search/:name')
searchCrypto(@GetUser() user: User, @Param('name') cryptoName: string) {
return this.cryptoService.searchCryptos(user.id, cryptoName);
}
@Get("/all")
getAllPromoCodes(@GetUser() user: User) {
return this.cryptoService.getCryptos(user.id);
}
@Get("/search/:name")
searchCrypto(@GetUser() user: User, @Param("name") cryptoName: string) {
return this.cryptoService.searchCryptos(user.id, cryptoName);
}
@Get('/history/:id')
CryptoHistory(@GetUser() user: User, @Param('id') cryptoId: string) {
return this.cryptoService.getCryptoHistory(user.id, cryptoId);
}
@Get("/history/:id")
CryptoHistory(@GetUser() user: User, @Param("id") cryptoId: string) {
return this.cryptoService.getCryptoHistory(user.id, cryptoId);
}
@HttpCode(HttpStatus.CREATED)
@Post('/create')
createPromoCode(
@Body()
dto: CryptoDto,
@GetUser() user: User,
) {
return this.cryptoService.createCrypto(user.id, dto);
}
@Post('/buy')
buyCrypto(
@Body()
dto: BuyCryptoDto,
@GetUser() user: User,
) {
return this.cryptoService.buyCrypto(user.id, dto);
}
@HttpCode(HttpStatus.OK)
@Patch('/update/:id')
editCryptoById(
@Param('id') cryptoId: string,
@Body() dto: CryptoDto,
@GetUser() user: User,
) {
return this.cryptoService.editCryptoById(user.id, cryptoId, dto);
}
@HttpCode(HttpStatus.CREATED)
@Post("/create")
createPromoCode(
@Body()
dto: CryptoDto,
@GetUser() user: User,
) {
return this.cryptoService.createCrypto(user.id, dto);
}
@Post("/buy")
buyCrypto(
@Body()
dto: BuyCryptoDto,
@GetUser() user: User,
) {
return this.cryptoService.buyCrypto(user.id, dto);
}
@HttpCode(HttpStatus.OK)
@Patch("/update/:id")
editCryptoById(
@Param("id") cryptoId: string,
@Body() dto: CryptoDto,
@GetUser() user: User,
) {
return this.cryptoService.editCryptoById(user.id, cryptoId, dto);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete('/delete/:id')
deleteOfferById(@Param('id') roleId: string, @GetUser() user: User) {
return this.cryptoService.deleteCryptoById(user.id, roleId);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete("/delete/:id")
deleteOfferById(@Param("id") roleId: string, @GetUser() user: User) {
return this.cryptoService.deleteCryptoById(user.id, roleId);
}
}

View File

@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { CryptoService } from './crypto.service';
import { CryptoController } from './crypto.controller';
import { Module } from "@nestjs/common";
import { CryptoController } from "./crypto.controller";
import { CryptoService } from "./crypto.service";
@Module({
providers: [CryptoService],
controllers: [CryptoController],
providers: [CryptoService],
controllers: [CryptoController],
})
export class CryptoModule {}

View File

@ -1,192 +1,192 @@
import { ForbiddenException, Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { checkUserHasAccount, checkUserIsAdmin } from 'src/utils/checkUser';
import { CryptoDto } from './dto';
import { BuyCryptoDto } from './dto/buy.crypto.dto';
import { ForbiddenException, Injectable } from "@nestjs/common";
import { checkUserHasAccount, checkUserIsAdmin } from "src/utils/checkUser";
import { PrismaService } from "../prisma/prisma.service";
import { CryptoDto } from "./dto";
import { BuyCryptoDto } from "./dto/buy.crypto.dto";
@Injectable()
export class CryptoService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) {}
async getCryptos(userId: string) {
await checkUserHasAccount(userId);
async getCryptos(userId: string) {
await checkUserHasAccount(userId);
return this.prisma.crypto.findMany({
orderBy: {
name: 'asc',
},
});
}
async searchCryptos(userId: string, cryptoName: string) {
await checkUserHasAccount(userId);
return this.prisma.crypto.findMany({
orderBy: {
name: "asc",
},
});
}
async searchCryptos(userId: string, cryptoName: string) {
await checkUserHasAccount(userId);
return this.prisma.crypto.findMany({
where: {
name: {
contains: cryptoName,
mode: 'insensitive',
},
},
orderBy: {
name: 'asc',
},
});
}
return this.prisma.crypto.findMany({
where: {
name: {
contains: cryptoName,
mode: "insensitive",
},
},
orderBy: {
name: "asc",
},
});
}
async getCryptoHistory(userId: string, cryptoId: string) {
await checkUserHasAccount(userId);
async getCryptoHistory(userId: string, cryptoId: string) {
await checkUserHasAccount(userId);
if (cryptoId) {
return this.prisma.crypto.findMany({
where: {
id: cryptoId,
},
if (cryptoId) {
return this.prisma.crypto.findMany({
where: {
id: cryptoId,
},
orderBy: {
created_at: 'desc',
},
take: 50,
});
}
throw new ForbiddenException('Crypto UUID required');
}
orderBy: {
created_at: "desc",
},
take: 50,
});
}
throw new ForbiddenException("Crypto UUID required");
}
async createCrypto(userId: string, dto: CryptoDto) {
await checkUserIsAdmin(userId);
async createCrypto(userId: string, dto: CryptoDto) {
await checkUserIsAdmin(userId);
const existingCryptosWithSameName = await this.prisma.crypto.findMany({
where: {
name: dto.name,
},
});
if (existingCryptosWithSameName.length > 0) {
throw new ForbiddenException('Name already taken');
}
const crypto = await this.prisma.crypto.create({
data: {
name: dto.name,
image: dto.image,
value: dto.value,
quantity: dto.quantity,
},
});
const existingCryptosWithSameName = await this.prisma.crypto.findMany({
where: {
name: dto.name,
},
});
if (existingCryptosWithSameName.length > 0) {
throw new ForbiddenException("Name already taken");
}
const crypto = await this.prisma.crypto.create({
data: {
name: dto.name,
image: dto.image,
value: dto.value,
quantity: dto.quantity,
},
});
return crypto;
}
return crypto;
}
async buyCrypto(userId: string, dto: BuyCryptoDto) {
const crypto = await this.prisma.crypto.findFirst({
where: {
id: dto.id_crypto,
},
});
async buyCrypto(userId: string, dto: BuyCryptoDto) {
const crypto = await this.prisma.crypto.findFirst({
where: {
id: dto.id_crypto,
},
});
const user = await this.prisma.user.findFirst({
where: {
id: userId,
},
});
if (crypto.quantity < dto.amount) {
throw new ForbiddenException('No more tokens available');
}
const necessaryAmount = crypto.value * dto.amount;
console.log(necessaryAmount, user.dollarAvailables);
const user = await this.prisma.user.findFirst({
where: {
id: userId,
},
});
if (crypto.quantity < dto.amount) {
throw new ForbiddenException("No more tokens available");
}
const necessaryAmount = crypto.value * dto.amount;
console.log(necessaryAmount, user.dollarAvailables);
if (necessaryAmount > user.dollarAvailables) {
throw new ForbiddenException('Make money first :) ');
}
const userAsset = await this.prisma.userHasCrypto.findFirst({
where: {
id_crypto: dto.id_crypto,
id_user: userId,
},
});
const newBalance = user.dollarAvailables - necessaryAmount;
console.log(newBalance);
if (necessaryAmount > user.dollarAvailables) {
throw new ForbiddenException("Make money first :) ");
}
const userAsset = await this.prisma.userHasCrypto.findFirst({
where: {
id_crypto: dto.id_crypto,
id_user: userId,
},
});
const newBalance = user.dollarAvailables - necessaryAmount;
console.log(newBalance);
await this.prisma.user.update({
where: {
id: user.id,
},
data: {
dollarAvailables: newBalance,
},
});
if (userAsset) {
const newBalance = userAsset.amount + dto.amount;
await this.prisma.userHasCrypto.update({
where: {
id: userAsset.id,
},
data: {
amount: newBalance,
},
});
} else {
await this.prisma.userHasCrypto.create({
data: {
id_crypto: dto.id_crypto,
id_user: userId,
amount: dto.amount,
},
});
}
const newCryptoValue = crypto.value * 1.1;
await this.prisma.user.update({
where: {
id: user.id,
},
data: {
dollarAvailables: newBalance,
},
});
if (userAsset) {
const newBalance = userAsset.amount + dto.amount;
await this.prisma.userHasCrypto.update({
where: {
id: userAsset.id,
},
data: {
amount: newBalance,
},
});
} else {
await this.prisma.userHasCrypto.create({
data: {
id_crypto: dto.id_crypto,
id_user: userId,
amount: dto.amount,
},
});
}
const newCryptoValue = crypto.value * 1.1;
await this.prisma.cryptoHistory.create({
data: {
id_crypto: crypto.id,
value: newCryptoValue,
},
});
const newQuantity = (crypto.quantity -= dto.amount);
return this.prisma.crypto.update({
where: {
id: dto.id_crypto,
},
data: {
value: newCryptoValue,
quantity: newQuantity,
},
});
}
async editCryptoById(userId: string, cryptoId: string, dto: CryptoDto) {
await checkUserIsAdmin(userId);
await this.prisma.cryptoHistory.create({
data: {
id_crypto: crypto.id,
value: newCryptoValue,
},
});
const newQuantity = (crypto.quantity -= dto.amount);
return this.prisma.crypto.update({
where: {
id: dto.id_crypto,
},
data: {
value: newCryptoValue,
quantity: newQuantity,
},
});
}
async editCryptoById(userId: string, cryptoId: string, dto: CryptoDto) {
await checkUserIsAdmin(userId);
const crypto = await this.prisma.crypto.findUnique({
where: {
id: cryptoId,
},
});
const crypto = await this.prisma.crypto.findUnique({
where: {
id: cryptoId,
},
});
if (!crypto || crypto.id !== cryptoId)
throw new ForbiddenException('Access to resources denied');
if (!crypto || crypto.id !== cryptoId)
throw new ForbiddenException("Access to resources denied");
return this.prisma.crypto.update({
where: {
id: crypto.id,
},
data: {
...dto,
},
});
}
return this.prisma.crypto.update({
where: {
id: crypto.id,
},
data: {
...dto,
},
});
}
async deleteCryptoById(userId: string, id: string) {
await checkUserIsAdmin(userId);
async deleteCryptoById(userId: string, id: string) {
await checkUserIsAdmin(userId);
const crypto = await this.prisma.crypto.findUnique({
where: {
id: id,
},
});
const crypto = await this.prisma.crypto.findUnique({
where: {
id: id,
},
});
if (!crypto || crypto.id !== id)
throw new ForbiddenException('Access to resources denied');
if (!crypto || crypto.id !== id)
throw new ForbiddenException("Access to resources denied");
await this.prisma.crypto.delete({
where: {
id: crypto.id,
},
});
}
await this.prisma.crypto.delete({
where: {
id: crypto.id,
},
});
}
}

View File

@ -1,32 +1,32 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
import {
IsNumber,
IsString,
IsUUID,
Max,
MaxLength,
Min,
MinLength,
} from 'class-validator';
IsNumber,
IsString,
IsUUID,
Max,
MaxLength,
Min,
MinLength,
} from "class-validator";
export class BuyCryptoDto {
@ApiProperty({
type: String,
description: 'Cryptocurrency UUID',
example: '12121-DSZD-E221212-2121221',
})
@MinLength(1)
@MaxLength(50)
@IsString()
@IsUUID()
id_crypto: string;
@ApiProperty({
type: String,
description: "Cryptocurrency UUID",
example: "12121-DSZD-E221212-2121221",
})
@MinLength(1)
@MaxLength(50)
@IsString()
@IsUUID()
id_crypto: string;
@ApiProperty({
type: Number,
description: 'Amount of token traded',
example: 2,
})
@Min(1)
@Max(1000)
@IsNumber()
amount: number;
@ApiProperty({
type: Number,
description: "Amount of token traded",
example: 2,
})
@Min(1)
@Max(1000)
@IsNumber()
amount: number;
}

View File

@ -1,54 +1,54 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
import {
IsNumber,
IsPositive,
IsString,
IsUrl,
Max,
MaxLength,
Min,
MinLength,
} from 'class-validator';
IsNumber,
IsPositive,
IsString,
IsUrl,
Max,
MaxLength,
Min,
MinLength,
} from "class-validator";
export class CryptoDto {
@ApiProperty({
type: String,
description: 'Cryptocurrency name',
example: 'BTC',
})
@MaxLength(50)
@MinLength(1)
@IsString()
name: string;
@ApiProperty({
type: String,
description: "Cryptocurrency name",
example: "BTC",
})
@MaxLength(50)
@MinLength(1)
@IsString()
name: string;
@ApiProperty({
type: Number,
description: 'Value for the cryptocurrency in $',
example: 1,
})
@Min(1)
@Max(10000)
@IsPositive()
@IsNumber()
value: number;
@ApiProperty({
type: Number,
description: "Value for the cryptocurrency in $",
example: 1,
})
@Min(1)
@Max(10000)
@IsPositive()
@IsNumber()
value: number;
@ApiProperty({
type: Number,
description: 'Quantity of tokens available on the platform',
example: 100,
})
@Min(1)
@Max(10000)
@IsPositive()
@IsNumber()
quantity: number;
@ApiProperty({
type: Number,
description: "Quantity of tokens available on the platform",
example: 100,
})
@Min(1)
@Max(10000)
@IsPositive()
@IsNumber()
quantity: number;
@ApiProperty({
type: String,
description: 'Image for the cryptocurrency in ',
example: 'https://myImage/com',
})
@MaxLength(255)
@IsUrl()
@IsString()
image: string;
@ApiProperty({
type: String,
description: "Image for the cryptocurrency in ",
example: "https://myImage/com",
})
@MaxLength(255)
@IsUrl()
@IsString()
image: string;
}

View File

@ -1 +1 @@
export * from './crypto.dto';
export * from "./crypto.dto";

View File

@ -1,26 +1,26 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { ValidationPipe } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
const app = await NestFactory.create(AppModule);
app.enableCors();
const config = new DocumentBuilder()
.setTitle('Neptune API')
.setDescription('A fictive app')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
const config = new DocumentBuilder()
.setTitle("Neptune API")
.setDescription("A fictive app")
.setVersion("1.0")
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup("api", app, document);
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
}),
);
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
}),
);
await app.listen(process.env.PORT || 3000);
await app.listen(process.env.PORT || 3000);
}
bootstrap();

View File

@ -1 +1 @@
export * from './offer.dto';
export * from "./offer.dto";

View File

@ -1,33 +1,32 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
import {
IsNumber,
IsPositive,
IsString,
IsUUID,
Max,
MaxLength,
Min,
} from 'class-validator';
IsNumber,
IsPositive,
IsString,
IsUUID,
Max,
MaxLength,
Min,
} from "class-validator";
export class OfferDto {
@ApiProperty({
type: String,
description: 'Cryptocurrency UUID',
example: '12121-DSZD-E221212-6227933',
})
@IsString()
@IsUUID()
id_crypto: string;
@ApiProperty({
type: String,
description: "Cryptocurrency UUID",
example: "12121-DSZD-E221212-6227933",
})
@IsString()
@IsUUID()
id_crypto: string;
@ApiProperty({
type: 'number',
@ApiProperty({
type: "number",
description: 'Amount traded ',
example: 21,
})
@Min(1)
@Max(1000)
@IsNumber()
@IsPositive()
amount: number;
description: "Amount traded ",
example: 21,
})
@Min(1)
@Max(1000)
@IsNumber()
@IsPositive()
amount: number;
}

View File

@ -1,58 +1,58 @@
import {
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
// UseGuards,
} from '@nestjs/common';
import { GetUser } from '../auth/decorator';
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
// UseGuards,
} from "@nestjs/common";
// import { JwtGuard } from '../auth/guard';
import { ApiTags } from '@nestjs/swagger';
import { User } from '@prisma/client';
import { JwtGuard } from 'src/auth/guard';
import { OfferService } from './offer.service';
import { OfferDto } from './dto';
import { ApiTags } from "@nestjs/swagger";
import { User } from "@prisma/client";
import { JwtGuard } from "src/auth/guard";
import { GetUser } from "../auth/decorator";
import { OfferDto } from "./dto";
import { OfferService } from "./offer.service";
@UseGuards(JwtGuard)
@ApiTags('offer')
@Controller('offer')
@ApiTags("offer")
@Controller("offer")
export class OfferController {
constructor(private offerService: OfferService) {}
constructor(private offerService: OfferService) {}
@Get('/all')
getAllRoles(@GetUser() user: User) {
return this.offerService.getOffers(user.id);
}
@Get("/all")
getAllRoles(@GetUser() user: User) {
return this.offerService.getOffers(user.id);
}
@HttpCode(HttpStatus.CREATED)
@Post('/create')
createRole(
@Body()
dto: OfferDto,
@GetUser() user: User,
) {
return this.offerService.createOffer(user.id, dto);
}
@HttpCode(HttpStatus.CREATED)
@Post("/create")
createRole(
@Body()
dto: OfferDto,
@GetUser() user: User,
) {
return this.offerService.createOffer(user.id, dto);
}
@HttpCode(HttpStatus.OK)
@Patch('/update/:id')
editOfferById(
@Param('id') offerId: string,
@Body() dto: OfferDto,
@GetUser() user: User,
) {
return this.offerService.editOfferById(user.id, offerId, dto);
}
@HttpCode(HttpStatus.OK)
@Patch("/update/:id")
editOfferById(
@Param("id") offerId: string,
@Body() dto: OfferDto,
@GetUser() user: User,
) {
return this.offerService.editOfferById(user.id, offerId, dto);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete('/delete/:id')
deleteOfferById(@Param('id') roleId: string, @GetUser() user: User) {
return this.offerService.deleteOfferById(user.id, roleId);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete("/delete/:id")
deleteOfferById(@Param("id") roleId: string, @GetUser() user: User) {
return this.offerService.deleteOfferById(user.id, roleId);
}
}

View File

@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { OfferService } from './offer.service';
import { OfferController } from './offer.controller';
import { Module } from "@nestjs/common";
import { OfferController } from "./offer.controller";
import { OfferService } from "./offer.service";
@Module({
providers: [OfferService],
controllers: [OfferController],
providers: [OfferService],
controllers: [OfferController],
})
export class OfferModule {}

View File

@ -1,88 +1,84 @@
import {ForbiddenException, Injectable} from "@nestjs/common";
import {PrismaService} from "@/prisma/prisma.service";
import {checkUserHasAccount, checkUserIsAdmin} from "src/utils/checkUser";
import {OfferDto} from "./dto";
import { PrismaService } from "@/prisma/prisma.service";
import { ForbiddenException, Injectable } from "@nestjs/common";
import { checkUserHasAccount, checkUserIsAdmin } from "src/utils/checkUser";
import { OfferDto } from "./dto";
@Injectable()
export class OfferService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) {}
async getOffers(userId: string) {
await checkUserHasAccount(userId);
return this.prisma.offer.findMany({
orderBy: {
created_at: 'desc',
},
select: {
amount: true,
created_at: true,
id_user: true,
Crypto: true,
},
});
}
async getOffers(userId: string) {
await checkUserHasAccount(userId);
return this.prisma.offer.findMany({
orderBy: {
created_at: "desc",
},
select: {
amount: true,
created_at: true,
id_user: true,
Crypto: true,
},
});
}
async createOffer(userId: string, dto: OfferDto) {
await checkUserHasAccount(userId);
return this.prisma.offer.create({
data: {
id_crypto: dto.id_crypto,
id_user: userId,
amount: dto.amount,
},
});
}
async createOffer(userId: string, dto: OfferDto) {
await checkUserHasAccount(userId);
return this.prisma.offer.create({
data: {
id_crypto: dto.id_crypto,
id_user: userId,
amount: dto.amount,
},
});
}
async editOfferById(userId: string, offerId: string, dto: OfferDto) {
await checkUserHasAccount(userId);
async editOfferById(userId: string, offerId: string, dto: OfferDto) {
await checkUserHasAccount(userId);
const offer = await this.prisma.offer.findUnique({
where: {
id: offerId,
},
});
const offer = await this.prisma.offer.findUnique({
where: {
id: offerId,
},
});
const crypto = await this.prisma.crypto.findUnique({
where: {
id: dto.id_crypto,
},
});
if (!crypto || !crypto.id) {
throw new ForbiddenException('Crypto doesnt exist');
}
const crypto = await this.prisma.crypto.findUnique({
where: {
id: dto.id_crypto,
},
});
if (!crypto || !crypto.id) {
throw new ForbiddenException("Crypto doesnt exist");
}
if (!offer || offer.id !== offerId)
throw new ForbiddenException('Offer id mandatory');
if (!offer || offer.id !== offerId)
throw new ForbiddenException("Offer id mandatory");
return this.prisma.offer.update({
where: {
id: offerId,
},
data: {
...dto,
},
});
}
async deleteOfferById(userId: string, id: string) {
await checkUserIsAdmin(userId);
return this.prisma.offer.update({
where: {
id: offerId,
},
data: {
...dto,
},
});
}
async deleteOfferById(userId: string, id: string) {
await checkUserIsAdmin(userId);
const offer = await this.prisma.offer.findUnique({
where: {
id: id,
},
});
const offer = await this.prisma.offer.findUnique({
where: {
id: id,
},
});
if (!offer || offer.id !== id)
throw new ForbiddenException('Access to resources denied');
if (!offer || offer.id !== id)
throw new ForbiddenException("Access to resources denied");
await this.prisma.offer.delete({
where: {
id: id,
},
});
}
await this.prisma.offer.delete({
where: {
id: id,
},
});
}
}

View File

@ -1,9 +1,9 @@
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { Global, Module } from "@nestjs/common";
import { PrismaService } from "./prisma.service";
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}

View File

@ -1,18 +1,17 @@
import { Injectable } from '@nestjs/common';
import { Injectable } from "@nestjs/common";
// biome-ignore lint/style/useImportType:
import { ConfigService } from '@nestjs/config';
import { PrismaClient } from '@prisma/client';
import { ConfigService } from "@nestjs/config";
import { PrismaClient } from "@prisma/client";
@Injectable()
export class PrismaService extends PrismaClient {
constructor(config: ConfigService) {
super({
datasources: {
db: {
url: config.get('DATABASE_URL'),
},
},
});
}
constructor(config: ConfigService) {
super({
datasources: {
db: {
url: config.get("DATABASE_URL"),
},
},
});
}
}

View File

@ -1 +1 @@
export * from './promoCode.dto';
export * from "./promoCode.dto";

View File

@ -1,32 +1,32 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty } from "@nestjs/swagger";
import {
IsNumber,
IsPositive,
IsString,
Max,
MaxLength,
Min,
MinLength,
} from 'class-validator';
IsNumber,
IsPositive,
IsString,
Max,
MaxLength,
Min,
MinLength,
} from "class-validator";
export class PromoCodeDto {
@ApiProperty({
type: String,
description: 'Name of the PromoCOde',
example: 'FILOU10',
})
@MinLength(1)
@MaxLength(50)
@IsString()
name: string;
@ApiProperty({
type: String,
description: "Name of the PromoCOde",
example: "FILOU10",
})
@MinLength(1)
@MaxLength(50)
@IsString()
name: string;
@ApiProperty({
type: Number,
description: 'Dollars given for account creation when promoCode applied',
example: 100,
})
@IsPositive()
@Min(1)
@Max(3000)
@IsNumber()
value: number;
@ApiProperty({
type: Number,
description: "Dollars given for account creation when promoCode applied",
example: 100,
})
@IsPositive()
@Min(1)
@Max(3000)
@IsNumber()
value: number;
}

View File

@ -1,57 +1,57 @@
import {
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
} from '@nestjs/common';
import { GetUser } from '../auth/decorator';
import { ApiTags } from '@nestjs/swagger';
import { User } from '@prisma/client';
import { PromoCodeDto } from './dto';
import { PromoCodeService } from './promoCode.service';
import { JwtGuard } from 'src/auth/guard';
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
} from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { User } from "@prisma/client";
import { JwtGuard } from "src/auth/guard";
import { GetUser } from "../auth/decorator";
import { PromoCodeDto } from "./dto";
import { PromoCodeService } from "./promoCode.service";
@UseGuards(JwtGuard)
@ApiTags('promoCode')
@Controller('promoCode')
@ApiTags("promoCode")
@Controller("promoCode")
export class PromoCodeController {
constructor(private promoService: PromoCodeService) {}
constructor(private promoService: PromoCodeService) {}
@Get('/all')
getAllPromoCodes(@GetUser() user: User) {
return this.promoService.getPromoCodes(user.id);
}
@Get("/all")
getAllPromoCodes(@GetUser() user: User) {
return this.promoService.getPromoCodes(user.id);
}
@HttpCode(HttpStatus.CREATED)
@Post('/create')
createPromoCode(
// @GetUser() user: User,
@Body()
dto: PromoCodeDto,
@GetUser() user: User,
) {
return this.promoService.createPromoCode(user.id, dto);
}
@HttpCode(HttpStatus.CREATED)
@Post("/create")
createPromoCode(
// @GetUser() user: User,
@Body()
dto: PromoCodeDto,
@GetUser() user: User,
) {
return this.promoService.createPromoCode(user.id, dto);
}
@HttpCode(HttpStatus.OK)
@Patch('/update/:id')
editPromoCodeById(
@Param('id') promoCodeId: string,
@Body() dto: PromoCodeDto,
@GetUser() user: User,
) {
return this.promoService.editPromoCodeById(user.id, promoCodeId, dto);
}
@HttpCode(HttpStatus.OK)
@Patch("/update/:id")
editPromoCodeById(
@Param("id") promoCodeId: string,
@Body() dto: PromoCodeDto,
@GetUser() user: User,
) {
return this.promoService.editPromoCodeById(user.id, promoCodeId, dto);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete('/delete/:id')
deletePromoCodeById(@Param('id') promoCodeId: string, @GetUser() user: User) {
return this.promoService.deletePromoCodeById(user.id, promoCodeId);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete("/delete/:id")
deletePromoCodeById(@Param("id") promoCodeId: string, @GetUser() user: User) {
return this.promoService.deletePromoCodeById(user.id, promoCodeId);
}
}

View File

@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { PromoCodeController } from './promoCode.controller';
import { PromoCodeService } from './promoCode.service';
import { Module } from "@nestjs/common";
import { PromoCodeController } from "./promoCode.controller";
import { PromoCodeService } from "./promoCode.service";
@Module({
providers: [PromoCodeService],
controllers: [PromoCodeController],
providers: [PromoCodeService],
controllers: [PromoCodeController],
})
export class PromoCodeModule {}

View File

@ -1,13 +1,13 @@
import { ForbiddenException } from '@nestjs/common';
// biome-ignore lint/style/useImportType:
import { Test, TestingModule } from '@nestjs/testing';
import { PrismaService } from "@/prisma/prisma.service";
import { PromoCodeService } from './promoCode.service';
import { checkUserIsAdmin } from "@/utils/checkUser";
import { ForbiddenException } from "@nestjs/common";
// biome-ignore lint/style/useImportType:
import { Test, TestingModule } from "@nestjs/testing";
import { PromoCodeService } from "./promoCode.service";
jest.mock('../utils/checkUser');
jest.mock("../utils/checkUser");
describe('PromoCodeService', () => {
describe("PromoCodeService", () => {
let service: PromoCodeService;
let prisma: PrismaService;
@ -37,35 +37,34 @@ describe('PromoCodeService', () => {
jest.clearAllMocks();
});
describe('getPromoCodes', () => {
it('should get promo codes if user is admin', async () => {
describe("getPromoCodes", () => {
it("should get promo codes if user is admin", async () => {
(checkUserIsAdmin as jest.Mock).mockResolvedValue(true);
const mockPromoCodes = [
{ id: '1', name: 'PROMO10', value: 10 },
{ id: '2', name: 'PROMO20', value: 20 },
{ id: "1", name: "PROMO10", value: 10 },
{ id: "2", name: "PROMO20", value: 20 },
];
mockPrismaService.promoCode.findMany.mockResolvedValue(mockPromoCodes);
const result = await service.getPromoCodes('user-id');
const result = await service.getPromoCodes("user-id");
expect(checkUserIsAdmin).toHaveBeenCalledWith('user-id');
expect(checkUserIsAdmin).toHaveBeenCalledWith("user-id");
expect(prisma.promoCode.findMany).toHaveBeenCalledWith({
orderBy: { name: 'asc' },
orderBy: { name: "asc" },
select: { id: true, name: true, value: true },
});
expect(result).toEqual(mockPromoCodes);
});
it('should throw ForbiddenException if user is not admin', async () => {
(checkUserIsAdmin as jest.Mock).mockRejectedValue(new ForbiddenException('Not an admin'));
await expect(service.getPromoCodes('user-id')).rejects.toThrow(
ForbiddenException,
it("should throw ForbiddenException if user is not admin", async () => {
(checkUserIsAdmin as jest.Mock).mockRejectedValue(
new ForbiddenException("Not an admin"),
);
expect(checkUserIsAdmin).toHaveBeenCalledWith('user-id');
await expect(service.getPromoCodes("user-id")).rejects.toThrow(ForbiddenException);
expect(checkUserIsAdmin).toHaveBeenCalledWith("user-id");
expect(prisma.promoCode.findMany).not.toHaveBeenCalled();
});
});
});

View File

@ -1,79 +1,75 @@
import { ForbiddenException, Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { PromoCodeDto } from './dto';
import { checkUserIsAdmin } from '../utils/checkUser';
import { ForbiddenException, Injectable } from "@nestjs/common";
import { PrismaService } from "../prisma/prisma.service";
import { checkUserIsAdmin } from "../utils/checkUser";
import { PromoCodeDto } from "./dto";
@Injectable()
export class PromoCodeService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) {}
async getPromoCodes(userId: string) {
await checkUserIsAdmin(userId);
async getPromoCodes(userId: string) {
await checkUserIsAdmin(userId);
return this.prisma.promoCode.findMany({
orderBy: {
name: 'asc',
},
select: {
id: true,
name: true,
value: true,
},
});
}
return this.prisma.promoCode.findMany({
orderBy: {
name: "asc",
},
select: {
id: true,
name: true,
value: true,
},
});
}
async createPromoCode(userId: string, dto: PromoCodeDto) {
await checkUserIsAdmin(userId);
async createPromoCode(userId: string, dto: PromoCodeDto) {
await checkUserIsAdmin(userId);
const promoCode = await this.prisma.promoCode.create({
data: {
name: dto.name,
value: dto.value,
},
});
const promoCode = await this.prisma.promoCode.create({
data: {
name: dto.name,
value: dto.value,
},
});
return promoCode;
}
async editPromoCodeById(
userId: string,
promoCodeId: string,
dto: PromoCodeDto,
) {
await checkUserIsAdmin(userId);
return promoCode;
}
async editPromoCodeById(userId: string, promoCodeId: string, dto: PromoCodeDto) {
await checkUserIsAdmin(userId);
const promoCode = await this.prisma.promoCode.findUnique({
where: {
id: promoCodeId,
},
});
const promoCode = await this.prisma.promoCode.findUnique({
where: {
id: promoCodeId,
},
});
if (!promoCode || promoCode.id !== promoCodeId)
throw new ForbiddenException('Access to resources denied');
if (!promoCode || promoCode.id !== promoCodeId)
throw new ForbiddenException("Access to resources denied");
return this.prisma.promoCode.update({
where: {
id: promoCode.id,
},
data: {
...dto,
},
});
}
async deletePromoCodeById(userId: string, id: string) {
await checkUserIsAdmin(userId);
return this.prisma.promoCode.update({
where: {
id: promoCode.id,
},
data: {
...dto,
},
});
}
async deletePromoCodeById(userId: string, id: string) {
await checkUserIsAdmin(userId);
const promoCode = await this.prisma.promoCode.findUnique({
where: {
id: id,
},
});
const promoCode = await this.prisma.promoCode.findUnique({
where: {
id: id,
},
});
if (!promoCode || promoCode.id !== id)
throw new ForbiddenException('Access to resources denied');
if (!promoCode || promoCode.id !== id)
throw new ForbiddenException("Access to resources denied");
await this.prisma.promoCode.delete({
where: {
id: promoCode.id,
},
});
}
await this.prisma.promoCode.delete({
where: {
id: promoCode.id,
},
});
}
}

View File

@ -1 +1 @@
export * from './role.dto';
export * from "./role.dto";

View File

@ -1,13 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, MaxLength, MinLength } from 'class-validator';
import { ApiProperty } from "@nestjs/swagger";
import { IsString, MaxLength, MinLength } from "class-validator";
export class RoleDto {
@ApiProperty({
type: String,
description: 'Role Name',
example: 'user',
})
@MinLength(1)
@MaxLength(50)
@IsString()
name: string;
@ApiProperty({
type: String,
description: "Role Name",
example: "user",
})
@MinLength(1)
@MaxLength(50)
@IsString()
name: string;
}

View File

@ -1,63 +1,59 @@
import {
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
// UseGuards,
} from '@nestjs/common';
import { GetUser } from '../auth/decorator';
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
// UseGuards,
} from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { User } from "@prisma/client";
import { JwtGuard } from "src/auth/guard";
import { GetUser } from "../auth/decorator";
// import { JwtGuard } from '../auth/guard';
import { RoleDto } from './dto';
import { RoleService } from './role.service';
import { ApiTags } from '@nestjs/swagger';
import { User } from '@prisma/client';
import { JwtGuard } from 'src/auth/guard';
import { RoleDto } from "./dto";
import { RoleService } from "./role.service";
@UseGuards(JwtGuard)
@ApiTags('role')
@Controller('role')
@ApiTags("role")
@Controller("role")
export class RoleController {
constructor(private roleService: RoleService) {}
constructor(private roleService: RoleService) {}
@Get('/all')
getAllRoles(@GetUser() user: User) {
return this.roleService.getRolesAdmin(user.id);
}
// @Get('/cm/all')
// getRolesCm(@GetUser() user: User) {
// return this.roleService.getRolesCm(user)
// }
@Get("/all")
getAllRoles(@GetUser() user: User) {
return this.roleService.getRolesAdmin(user.id);
}
// @Get('/cm/all')
// getRolesCm(@GetUser() user: User) {
// return this.roleService.getRolesCm(user)
// }
@HttpCode(HttpStatus.CREATED)
@Post('/create')
createRole(
// @GetUser() user: User,
@Body()
dto: RoleDto,
@GetUser() user: User,
) {
return this.roleService.createRole(user.id, dto);
}
@HttpCode(HttpStatus.CREATED)
@Post("/create")
createRole(
// @GetUser() user: User,
@Body()
dto: RoleDto,
@GetUser() user: User,
) {
return this.roleService.createRole(user.id, dto);
}
@HttpCode(HttpStatus.OK)
@Patch('/update/:id')
editRoleById(
@Param('id') roleId: string,
@Body() dto: RoleDto,
@GetUser() user: User,
) {
return this.roleService.editRoleById(user.id, roleId, dto);
}
@HttpCode(HttpStatus.OK)
@Patch("/update/:id")
editRoleById(@Param("id") roleId: string, @Body() dto: RoleDto, @GetUser() user: User) {
return this.roleService.editRoleById(user.id, roleId, dto);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete('/delete/:id')
deleteRoleById(@Param('id') roleId: string, @GetUser() user: User) {
return this.roleService.deleteRoleById(user.id, roleId);
}
@HttpCode(HttpStatus.NO_CONTENT)
@Delete("/delete/:id")
deleteRoleById(@Param("id") roleId: string, @GetUser() user: User) {
return this.roleService.deleteRoleById(user.id, roleId);
}
}

View File

@ -1,8 +1,8 @@
import { Module } from '@nestjs/common';
import { RoleController } from './role.controller';
import { RoleService } from './role.service';
import { Module } from "@nestjs/common";
import { RoleController } from "./role.controller";
import { RoleService } from "./role.service";
@Module({
providers: [RoleService],
controllers: [RoleController],
providers: [RoleService],
controllers: [RoleController],
})
export class RoleModule {}

View File

@ -1,72 +1,72 @@
import { ForbiddenException, Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { RoleDto } from './dto';
import { checkUserIsAdmin } from 'src/utils/checkUser';
import { ForbiddenException, Injectable } from "@nestjs/common";
import { checkUserIsAdmin } from "src/utils/checkUser";
import { PrismaService } from "../prisma/prisma.service";
import { RoleDto } from "./dto";
// import { checkRoleLevel, checkUserIsStaff } from 'src/utils/checkUser';
@Injectable()
export class RoleService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) {}
async getRolesAdmin(userId: string) {
await checkUserIsAdmin(userId);
return this.prisma.role.findMany({
orderBy: {
name: 'asc',
},
select: {
id: true,
name: true,
},
});
}
async getRolesAdmin(userId: string) {
await checkUserIsAdmin(userId);
return this.prisma.role.findMany({
orderBy: {
name: "asc",
},
select: {
id: true,
name: true,
},
});
}
async createRole(userId: string, dto: RoleDto) {
await checkUserIsAdmin(userId);
const role = await this.prisma.role.create({
data: {
name: dto.name,
},
});
async createRole(userId: string, dto: RoleDto) {
await checkUserIsAdmin(userId);
const role = await this.prisma.role.create({
data: {
name: dto.name,
},
});
return role;
}
async editRoleById(userId: string, roleId: string, dto: RoleDto) {
await checkUserIsAdmin(userId);
return role;
}
async editRoleById(userId: string, roleId: string, dto: RoleDto) {
await checkUserIsAdmin(userId);
const role = await this.prisma.role.findUnique({
where: {
id: roleId,
},
});
const role = await this.prisma.role.findUnique({
where: {
id: roleId,
},
});
if (!role || role.id !== roleId)
throw new ForbiddenException('Access to resources denied');
if (!role || role.id !== roleId)
throw new ForbiddenException("Access to resources denied");
return this.prisma.role.update({
where: {
id: roleId,
},
data: {
...dto,
},
});
}
async deleteRoleById(userId: string, id: string) {
await checkUserIsAdmin(userId);
return this.prisma.role.update({
where: {
id: roleId,
},
data: {
...dto,
},
});
}
async deleteRoleById(userId: string, id: string) {
await checkUserIsAdmin(userId);
const role = await this.prisma.role.findUnique({
where: {
id: id,
},
});
const role = await this.prisma.role.findUnique({
where: {
id: id,
},
});
if (!role || role.id !== id)
throw new ForbiddenException('Access to resources denied');
if (!role || role.id !== id)
throw new ForbiddenException("Access to resources denied");
await this.prisma.role.delete({
where: {
id: id,
},
});
}
await this.prisma.role.delete({
where: {
id: id,
},
});
}
}

View File

@ -1 +1 @@
export * from './trade.dto';
export * from "./trade.dto";

View File

@ -1,13 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString, IsUUID } from 'class-validator';
import { ApiProperty } from "@nestjs/swagger";
import { IsNotEmpty, IsString, IsUUID } from "class-validator";
export class TradeDto {
@ApiProperty({
type: String,
description: 'Offer UUID ',
example: '121212-DSDZ1-21212DJDZ-31313',
})
@IsUUID()
@IsNotEmpty()
@IsString()
id_offer: string;
@ApiProperty({
type: String,
description: "Offer UUID ",
example: "121212-DSDZ1-21212DJDZ-31313",
})
@IsUUID()
@IsNotEmpty()
@IsString()
id_offer: string;
}

View File

@ -1,38 +1,38 @@
import {
Body,
Controller,
Get,
HttpCode,
HttpStatus,
Post,
UseGuards,
} from '@nestjs/common';
import { GetUser } from '../auth/decorator';
import { ApiTags } from '@nestjs/swagger';
import { User } from '@prisma/client';
import { TradeService } from './trade.service';
import { TradeDto } from './dto';
import { JwtGuard } from 'src/auth/guard';
Body,
Controller,
Get,
HttpCode,
HttpStatus,
Post,
UseGuards,
} from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { User } from "@prisma/client";
import { JwtGuard } from "src/auth/guard";
import { GetUser } from "../auth/decorator";
import { TradeDto } from "./dto";
import { TradeService } from "./trade.service";
@UseGuards(JwtGuard)
@ApiTags('trade')
@Controller('trade')
@ApiTags("trade")
@Controller("trade")
export class TradeController {
constructor(private tradeService: TradeService) {}
constructor(private tradeService: TradeService) {}
@Get('/all')
getAllPromoCodes(@GetUser() user: User) {
return this.tradeService.getTrades(user.id);
}
@Get("/all")
getAllPromoCodes(@GetUser() user: User) {
return this.tradeService.getTrades(user.id);
}
@HttpCode(HttpStatus.CREATED)
@Post('/create')
createPromoCode(
// @GetUser() user: User,
@Body()
dto: TradeDto,
@GetUser() user: User,
) {
return this.tradeService.createTrade(user.id, dto);
}
@HttpCode(HttpStatus.CREATED)
@Post("/create")
createPromoCode(
// @GetUser() user: User,
@Body()
dto: TradeDto,
@GetUser() user: User,
) {
return this.tradeService.createTrade(user.id, dto);
}
}

View File

@ -1,9 +1,9 @@
import { Module } from '@nestjs/common';
import { TradeService } from './trade.service';
import { TradeController } from './trade.controller';
import { Module } from "@nestjs/common";
import { TradeController } from "./trade.controller";
import { TradeService } from "./trade.service";
@Module({
providers: [TradeService],
controllers: [TradeController],
providers: [TradeService],
controllers: [TradeController],
})
export class TradeModule {}

View File

@ -1,173 +1,173 @@
import { ForbiddenException, Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { checkUserHasAccount, checkUserIsAdmin } from 'src/utils/checkUser';
import { TradeDto } from './dto';
import { ForbiddenException, Injectable } from "@nestjs/common";
import { checkUserHasAccount, checkUserIsAdmin } from "src/utils/checkUser";
import { PrismaService } from "../prisma/prisma.service";
import { TradeDto } from "./dto";
@Injectable()
export class TradeService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) {}
async getTrades(userId: string) {
await checkUserIsAdmin(userId);
async getTrades(userId: string) {
await checkUserIsAdmin(userId);
return this.prisma.trade.findMany({
orderBy: {
created_at: 'desc',
},
// include: {
// Giver: true,
// Receiver: true,
// Crypto: true,
// },
return this.prisma.trade.findMany({
orderBy: {
created_at: "desc",
},
// include: {
// Giver: true,
// Receiver: true,
// Crypto: true,
// },
select: {
Giver: {
select: {
firstName: true,
lastName: true,
pseudo: true,
dollarAvailables: true,
},
},
Receiver: {
select: {
firstName: true,
lastName: true,
pseudo: true,
dollarAvailables: true,
},
},
Crypto: true,
},
});
}
async getLastTrades() {
return this.prisma.trade.findMany({
orderBy: {
created_at: 'desc',
},
select: {
amount_traded: true,
Crypto: true,
},
});
}
select: {
Giver: {
select: {
firstName: true,
lastName: true,
pseudo: true,
dollarAvailables: true,
},
},
Receiver: {
select: {
firstName: true,
lastName: true,
pseudo: true,
dollarAvailables: true,
},
},
Crypto: true,
},
});
}
async getLastTrades() {
return this.prisma.trade.findMany({
orderBy: {
created_at: "desc",
},
select: {
amount_traded: true,
Crypto: true,
},
});
}
async createTrade(userId: string, dto: TradeDto) {
await checkUserHasAccount(userId);
async createTrade(userId: string, dto: TradeDto) {
await checkUserHasAccount(userId);
const offer = await this.prisma.offer.findUnique({
where: {
id: dto.id_offer,
},
});
const crypto = await this.prisma.crypto.findFirst({
where: {
id: offer.id_crypto,
},
});
const offer = await this.prisma.offer.findUnique({
where: {
id: dto.id_offer,
},
});
const crypto = await this.prisma.crypto.findFirst({
where: {
id: offer.id_crypto,
},
});
const buyer = await this.prisma.user.findFirst({
where: {
id: offer.id_user,
},
});
const buyer = await this.prisma.user.findFirst({
where: {
id: offer.id_user,
},
});
const price = crypto.value * offer.amount;
if (buyer.dollarAvailables < price) {
throw new ForbiddenException(
`Acqueror ${buyer.pseudo} doesnt have enough money to make this trade`,
);
}
const price = crypto.value * offer.amount;
if (buyer.dollarAvailables < price) {
throw new ForbiddenException(
`Acqueror ${buyer.pseudo} doesnt have enough money to make this trade`,
);
}
const asset = await this.prisma.userHasCrypto.findFirst({
where: {
id_crypto: offer.id_crypto,
id_user: offer.id_user,
},
});
const asset = await this.prisma.userHasCrypto.findFirst({
where: {
id_crypto: offer.id_crypto,
id_user: offer.id_user,
},
});
if (!asset || asset.amount < offer.amount) {
throw new ForbiddenException(`Seller doesnt have enough ${crypto.name} `);
}
if (!asset || asset.amount < offer.amount) {
throw new ForbiddenException(`Seller doesnt have enough ${crypto.name} `);
}
const trade = await this.prisma.trade.create({
data: {
id_giver: offer.id_user,
id_receiver: userId,
id_crypto: offer.id_crypto,
amount_traded: offer.amount,
},
});
const trade = await this.prisma.trade.create({
data: {
id_giver: offer.id_user,
id_receiver: userId,
id_crypto: offer.id_crypto,
amount_traded: offer.amount,
},
});
const newBalanceGiver = (asset.amount -= offer.amount);
await this.prisma.userHasCrypto.update({
where: {
id: asset.id,
},
data: {
amount: newBalanceGiver,
},
});
const newBalanceGiver = (asset.amount -= offer.amount);
await this.prisma.userHasCrypto.update({
where: {
id: asset.id,
},
data: {
amount: newBalanceGiver,
},
});
const receiverAssets = await this.prisma.userHasCrypto.findFirst({
where: {
id_user: userId,
id_crypto: offer.id_crypto,
},
});
if (!receiverAssets) {
await this.prisma.userHasCrypto.create({
data: {
id_user: userId,
id_crypto: offer.id_crypto,
amount: offer.amount,
createdAt: new Date(),
},
});
} else {
const newBalanceReceiver = receiverAssets.amount + offer.amount;
await this.prisma.userHasCrypto.update({
where: {
id: receiverAssets.id,
},
data: {
amount: newBalanceReceiver,
},
});
}
const receiverAssets = await this.prisma.userHasCrypto.findFirst({
where: {
id_user: userId,
id_crypto: offer.id_crypto,
},
});
if (!receiverAssets) {
await this.prisma.userHasCrypto.create({
data: {
id_user: userId,
id_crypto: offer.id_crypto,
amount: offer.amount,
createdAt: new Date(),
},
});
} else {
const newBalanceReceiver = receiverAssets.amount + offer.amount;
await this.prisma.userHasCrypto.update({
where: {
id: receiverAssets.id,
},
data: {
amount: newBalanceReceiver,
},
});
}
const newValue = crypto.value * 1.1;
await this.prisma.cryptoHistory.create({
data: {
id_crypto: crypto.id,
value: newValue,
},
});
const newValue = crypto.value * 1.1;
await this.prisma.cryptoHistory.create({
data: {
id_crypto: crypto.id,
value: newValue,
},
});
await this.prisma.crypto.update({
where: {
id: crypto.id,
},
data: {
value: newValue,
},
});
await this.prisma.crypto.update({
where: {
id: crypto.id,
},
data: {
value: newValue,
},
});
const prevAmount = buyer.dollarAvailables;
const prevAmount = buyer.dollarAvailables;
await this.prisma.user.update({
where: {
id: userId,
},
data: {
dollarAvailables: prevAmount - price,
},
});
await this.prisma.offer.delete({
where: {
id: offer.id,
},
});
return trade;
}
await this.prisma.user.update({
where: {
id: userId,
},
data: {
dollarAvailables: prevAmount - price,
},
});
await this.prisma.offer.delete({
where: {
id: offer.id,
},
});
return trade;
}
}

View File

@ -1,36 +1,36 @@
import { Controller, Get, UseGuards } from '@nestjs/common';
import { GetUser } from '../auth/decorator';
import { JwtGuard } from '../auth/guard';
import { ApiTags } from '@nestjs/swagger';
import { UserService } from './user.service';
import { User } from '@prisma/client';
import { Controller, Get, UseGuards } from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { User } from "@prisma/client";
import { GetUser } from "../auth/decorator";
import { JwtGuard } from "../auth/guard";
import { UserService } from "./user.service";
@ApiTags('user')
@ApiTags("user")
@UseGuards(JwtGuard)
@Controller('user')
@Controller("user")
export class UserController {
constructor(private userService: UserService) {}
constructor(private userService: UserService) {}
@Get('/my-assets')
GetMyAssets(
@GetUser()
user: User,
) {
return this.userService.getMyAssets(user.id);
}
@Get("/my-assets")
GetMyAssets(
@GetUser()
user: User,
) {
return this.userService.getMyAssets(user.id);
}
@Get('/users-assets')
GetAlLAssets(
@GetUser()
user: User,
) {
return this.userService.getUsersAssets(user.id);
}
@Get('/my-trades')
GetMyTrades(
@GetUser()
user: User,
) {
return this.userService.getMyTrades(user.id);
}
@Get("/users-assets")
GetAlLAssets(
@GetUser()
user: User,
) {
return this.userService.getUsersAssets(user.id);
}
@Get("/my-trades")
GetMyTrades(
@GetUser()
user: User,
) {
return this.userService.getMyTrades(user.id);
}
}

View File

@ -1,8 +1,8 @@
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { Module } from "@nestjs/common";
import { UserController } from "./user.controller";
import { UserService } from "./user.service";
@Module({
providers: [UserService],
controllers: [UserController],
providers: [UserService],
controllers: [UserController],
})
export class UserModule {}

View File

@ -1,81 +1,80 @@
import {Injectable} from "@nestjs/common";
import {PrismaService} from "@/prisma/prisma.service";
import {checkUserHasAccount, checkUserIsAdmin} from "src/utils/checkUser";
import { PrismaService } from "@/prisma/prisma.service";
import { Injectable } from "@nestjs/common";
import { checkUserHasAccount, checkUserIsAdmin } from "src/utils/checkUser";
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
constructor(private prisma: PrismaService) {}
/**
* Retrieves the assets of a given user, including their first name, last name, available dollars,
* pseudo, and associated cryptocurrencies.
*
* @param {string} userId - The unique identifier of the user whose assets are being retrieved.
* @return A promise that resolves to an object containing the user's assets and associated data.
*/
async getMyAssets(userId: string) {
await checkUserHasAccount(userId);
/**
* Retrieves the assets of a given user, including their first name, last name, available dollars,
* pseudo, and associated cryptocurrencies.
*
* @param {string} userId - The unique identifier of the user whose assets are being retrieved.
* @return A promise that resolves to an object containing the user's assets and associated data.
*/
async getMyAssets(userId: string) {
await checkUserHasAccount(userId);
return this.prisma.user.findUnique({
where: {
id: userId,
},
select: {
firstName: true,
lastName: true,
dollarAvailables: true,
pseudo: true,
UserHasCrypto: {
select: {
Crypto: true,
},
},
},
});
}
return this.prisma.user.findUnique({
where: {
id: userId,
},
select: {
firstName: true,
lastName: true,
dollarAvailables: true,
pseudo: true,
UserHasCrypto: {
select: {
Crypto: true,
},
},
},
});
}
/**
* Retrieves the assets of users based on user ID.
*
* @param {string} userId - The ID of the user requesting the assets.
* @return A promise that resolves to an array of user assets.
*/
async getUsersAssets(userId: string) {
await checkUserIsAdmin(userId);
/**
* Retrieves the assets of users based on user ID.
*
* @param {string} userId - The ID of the user requesting the assets.
* @return A promise that resolves to an array of user assets.
*/
async getUsersAssets(userId: string) {
await checkUserIsAdmin(userId);
return this.prisma.user.findMany({
select: {
firstName: true,
lastName: true,
pseudo: true,
dollarAvailables: true,
UserHasCrypto: {
select: {
Crypto: true,
amount: true,
},
},
},
take: 20,
});
}
return this.prisma.user.findMany({
select: {
firstName: true,
lastName: true,
pseudo: true,
dollarAvailables: true,
UserHasCrypto: {
select: {
Crypto: true,
amount: true,
},
},
},
take: 20,
});
}
/**
* Fetches all trades associated with a given user.
*
* @param {string} userId - The unique identifier of the user.
* @return A promise that resolves to an array of trade objects.
*/
async getMyTrades(userId: string) {
await checkUserHasAccount(userId);
return this.prisma.trade.findMany({
where: {
OR: [{id_giver: userId}, {id_receiver: userId}],
},
include: {
Crypto: true,
},
});
}
/**
* Fetches all trades associated with a given user.
*
* @param {string} userId - The unique identifier of the user.
* @return A promise that resolves to an array of trade objects.
*/
async getMyTrades(userId: string) {
await checkUserHasAccount(userId);
return this.prisma.trade.findMany({
where: {
OR: [{ id_giver: userId }, { id_receiver: userId }],
},
include: {
Crypto: true,
},
});
}
}

View File

@ -1,86 +1,86 @@
import { ForbiddenException } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { Roles } from './const/const';
import { ForbiddenException } from "@nestjs/common";
import { PrismaClient } from "@prisma/client";
import { Roles } from "./const/const";
const prisma = new PrismaClient();
export async function checkRoleLevel(userId: string, level: string) {
if (!userId || !level) {
throw new ForbiddenException('Access to resources denied');
}
if (!userId || !level) {
throw new ForbiddenException("Access to resources denied");
}
checkRoleExist(level);
checkRoleExist(level);
const user = await prisma.user.findUnique({
where: {
id: userId,
},
});
if (user?.roleId) {
const role = await prisma.role.findFirst({
where: {
id: user.roleId,
},
});
const user = await prisma.user.findUnique({
where: {
id: userId,
},
});
if (user?.roleId) {
const role = await prisma.role.findFirst({
where: {
id: user.roleId,
},
});
if (role?.id) {
checkRoleExist(role.name);
if (level === Roles.ADMIN && role.name !== Roles.ADMIN) {
throw new ForbiddenException('Access to resources denied');
}
} else {
throw new ForbiddenException('Access to resources denied');
}
} else {
throw new ForbiddenException('Access to resources denied');
}
if (role?.id) {
checkRoleExist(role.name);
if (level === Roles.ADMIN && role.name !== Roles.ADMIN) {
throw new ForbiddenException("Access to resources denied");
}
} else {
throw new ForbiddenException("Access to resources denied");
}
} else {
throw new ForbiddenException("Access to resources denied");
}
}
function checkRoleExist(role: string) {
switch (role) {
case Roles.ADMIN:
case Roles.USER:
break;
default:
throw new ForbiddenException('Access to resources denied');
}
switch (role) {
case Roles.ADMIN:
case Roles.USER:
break;
default:
throw new ForbiddenException("Access to resources denied");
}
}
export async function checkUserHasAccount(jwtId: string) {
if (jwtId) {
const user = await prisma.user.findUnique({
where: {
id: jwtId,
isActive: true,
},
});
if (!user || !user.id) {
throw new ForbiddenException('Access to resources denied');
}
} else {
throw new ForbiddenException('Access to resources denied');
}
if (jwtId) {
const user = await prisma.user.findUnique({
where: {
id: jwtId,
isActive: true,
},
});
if (!user || !user.id) {
throw new ForbiddenException("Access to resources denied");
}
} else {
throw new ForbiddenException("Access to resources denied");
}
}
export async function checkUserIsAdmin(jwtId: string) {
if (jwtId) {
const user = await prisma.user.findUnique({
where: {
id: jwtId,
isActive: true,
},
include: {
Role: true,
},
});
if (!user || !user.id) {
throw new ForbiddenException('Access to resources denied2');
}
if (jwtId) {
const user = await prisma.user.findUnique({
where: {
id: jwtId,
isActive: true,
},
include: {
Role: true,
},
});
if (!user || !user.id) {
throw new ForbiddenException("Access to resources denied2");
}
if (user.Role.name !== Roles.ADMIN) {
throw new ForbiddenException('Access to resources denied3');
}
} else {
throw new ForbiddenException('Access to resources denied4');
}
if (user.Role.name !== Roles.ADMIN) {
throw new ForbiddenException("Access to resources denied3");
}
} else {
throw new ForbiddenException("Access to resources denied4");
}
}

View File

@ -1,4 +1,4 @@
export const Roles = {
ADMIN: 'admin',
USER: 'user',
ADMIN: "admin",
USER: "user",
};

View File

@ -1,16 +1,16 @@
// auth/test/mocks.ts
import { User } from '@prisma/client';
import { User } from "@prisma/client";
export const getMockUser = (): User => ({
id: 'user-id',
email: 'test@example.com',
firstName: 'Test User',
lastName: 'Test',
hash: 'test-hash',
pseudo: 'test-pseudo',
isActive: true,
created_at: new Date(),
updated_at: new Date(),
roleId: 'user',
dollarAvailables: 1000,
id: "user-id",
email: "test@example.com",
firstName: "Test User",
lastName: "Test",
hash: "test-hash",
pseudo: "test-pseudo",
isActive: true,
created_at: new Date(),
updated_at: new Date(),
roleId: "user",
dollarAvailables: 1000,
});