From c95e55f625e09adb9755b414e1861bdfc8809092 Mon Sep 17 00:00:00 2001 From: Artem-Darius Atlas Date: Thu, 29 Jun 2023 16:11:23 +0300 Subject: [PATCH] feat: added device module for the auth service --- apps/auth/src/device/device.controller.ts | 84 +++++++++++++++++++ apps/auth/src/device/device.module.ts | 11 +++ .../auth/src/device/service/device.service.ts | 64 ++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 apps/auth/src/device/device.controller.ts create mode 100644 apps/auth/src/device/device.module.ts create mode 100644 apps/auth/src/device/service/device.service.ts diff --git a/apps/auth/src/device/device.controller.ts b/apps/auth/src/device/device.controller.ts new file mode 100644 index 0000000..dd29534 --- /dev/null +++ b/apps/auth/src/device/device.controller.ts @@ -0,0 +1,84 @@ +import { Body, ConflictException, Controller, HttpCode, Post, ValidationPipe } from "@nestjs/common"; +import { DeviceService } from "./service/device.service"; +import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; +import { RegisterDto } from "./dto/register.dto"; +import { FingerprintDto } from "./dto/fingerprint.dto"; +import { UserDto } from "./dto/user.dto"; + +@Controller("device") +export class DeviceController { + constructor(private readonly device: DeviceService) { + } + + @Post("user") + @HttpCode(200) + async User(@Body(new ValidationPipe()) params: UserDto) { + return this.device.User(params); + } + + @Post("is-exists") + @HttpCode(200) + async IsExists(@Body(new ValidationPipe()) params: FingerprintDto) { + return await this.device.isExists(params); + } + + @Post("register") + @HttpCode(200) + async Register(@Body(new ValidationPipe()) params: RegisterDto) { + try { + await this.device.register(params); + } catch (e) { + if (!(e instanceof PrismaClientKnownRequestError)) throw e; + if (e.code === "P2002") throw new ConflictException("device with the same fingerprint already exists"); + if (e.code === "P2003") throw new ConflictException("user with this uuid does not exist"); + throw e; + } + } + + + @Post("delete") + @HttpCode(200) + async Delete(@Body(new ValidationPipe()) params: FingerprintDto) { + try { + await this.device.delete(params); + } catch (e) { + if (!(e instanceof PrismaClientKnownRequestError)) throw e; + if (e.code !== "P2025") throw e; + throw new ConflictException("device with this fingerprint does not exist"); + } + } + + + @Post("block") + @HttpCode(200) + async Block(@Body(new ValidationPipe()) params: FingerprintDto) { + try { + await this.device.block(params); + } catch (e) { + if (!(e instanceof PrismaClientKnownRequestError)) throw e; + if (e.code !== "P2025") throw e; + throw new ConflictException("device with this fingerprint does not exist"); + } + } + + @Post("unblock") + @HttpCode(200) + async Unblock(@Body(new ValidationPipe()) params: FingerprintDto) { + try { + await this.device.unblock(params); + } catch (e) { + if (!(e instanceof PrismaClientKnownRequestError)) throw e; + if (e.code !== "P2025") throw e; + throw new ConflictException("device with this fingerprint does not exist"); + } + } + + + @Post("is-blocked") + @HttpCode(200) + async IsBlocked(@Body(new ValidationPipe()) params: FingerprintDto) { + const isBlocked = await this.device.isBlocked(params); + if (isBlocked !== null) return isBlocked.isBlocked; + throw new ConflictException("device with this fingerprint does not exist"); + } +} diff --git a/apps/auth/src/device/device.module.ts b/apps/auth/src/device/device.module.ts new file mode 100644 index 0000000..706f553 --- /dev/null +++ b/apps/auth/src/device/device.module.ts @@ -0,0 +1,11 @@ +import { Module } from "@nestjs/common"; +import { DeviceController } from "./device.controller"; +import { DeviceService } from "./service/device.service"; + +@Module({ + providers: [DeviceService], + controllers: [DeviceController], + exports: [DeviceService] +}) +export class DeviceModule { +} \ No newline at end of file diff --git a/apps/auth/src/device/service/device.service.ts b/apps/auth/src/device/service/device.service.ts new file mode 100644 index 0000000..5e0e462 --- /dev/null +++ b/apps/auth/src/device/service/device.service.ts @@ -0,0 +1,64 @@ +import { BadRequestException, ConflictException, Injectable } from "@nestjs/common"; +import { PrismaService } from "../../Prisma/service/prisma.service"; +import { UserDto } from "../dto/user.dto"; +import { PrismaClientValidationError } from "@prisma/client/runtime"; + +@Injectable() +export class DeviceService { + constructor(private readonly prisma: PrismaService) { + } + + public getUserUuidAsPrismaPromise(params: { fingerprint: string }) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + return this.prisma.userDevice.findUnique({ where: { fingerprint }, select: { userUuid: true } }); + } + + public async User(params: UserDto) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + let select: { uuid?: boolean, isBlocked?: boolean } | undefined = { uuid: true, isBlocked: true }; + if (params.select !== undefined && params.select !== null) { + select = {}; + if (params.select.uuid !== undefined && params.select.uuid !== null) select.uuid = params.select.uuid; + if (params.select.isBlocked !== undefined && params.select.isBlocked !== null) select.isBlocked = params.select.isBlocked; + } + try { + const res: { user: { uuid?: string, isBlocked?: boolean } } | null = + await this.prisma.userDevice.findUnique({ where: { fingerprint }, select: { user: { select } } }); + if (res === null) throw new ConflictException("device with this fingerprint does not exist"); + return res.user; + } catch (e) { + if (!(e instanceof PrismaClientValidationError)) throw e; + throw new BadRequestException("The select statement needs at least one truthy value."); + } + } + + public async isExists(params: { fingerprint: string }) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + return (await this.prisma.userDevice.findUnique({ where: { fingerprint }, select: null }) !== null); + } + + public register(params: { userUuid: string, name: string, fingerprint: string }) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + return this.prisma.userDevice.create({ data: { ...params, fingerprint }, select: null }); + } + + public async delete(params: { fingerprint: string }) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + await this.prisma.userDevice.delete({ where: { fingerprint }, select: null }); + } + + public async block(params: { fingerprint: string }) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + await this.prisma.userDevice.update({ where: { fingerprint }, data: { isBlocked: true }, select: null }); + } + + public async unblock(params: { fingerprint: string }) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + await this.prisma.userDevice.update({ where: { fingerprint }, data: { isBlocked: false }, select: null }); + } + + public isBlocked(params: { fingerprint: string }) { + const fingerprint = Buffer.from(params.fingerprint, "hex"); + return this.prisma.userDevice.findUnique({ where: { fingerprint }, select: { isBlocked: true } }); + } +}