diff --git a/src/app/api/idnot/UserController.ts b/src/app/api/idnot/UserController.ts index 60d13059..77d79065 100644 --- a/src/app/api/idnot/UserController.ts +++ b/src/app/api/idnot/UserController.ts @@ -5,11 +5,14 @@ import { Service } from "typedi"; import AuthService, { IUserJwtPayload } from "@Services/common/AuthService/AuthService"; import IdNotService from "@Services/common/IdNotService/IdNotService"; +import WhitelistService from "@Services/common/WhitelistService/WhitelistService"; +import User from "le-coffre-resources/dist/SuperAdmin"; +import UsersService from "@Services/super-admin/UsersService/UsersService"; @Controller() @Service() export default class UserController extends ApiController { - constructor(private authService: AuthService, private idNotService: IdNotService) { + constructor(private authService: AuthService, private idNotService: IdNotService, private whitelistService: WhitelistService, private userService: UsersService) { super(); } @@ -25,6 +28,7 @@ export default class UserController extends ApiController { if (!code) throw new Error("code is required"); const idNotToken = await this.idNotService.getIdNotToken(code); + if(!idNotToken) { this.httpValidationError(response, "IdNot token undefined"); return; @@ -35,7 +39,28 @@ export default class UserController extends ApiController { this.httpUnauthorized(response); return; } - await this.idNotService.updateUser(user.uid); + + //Whitelist feature + //Get user with contact + const prismaUser = await this.userService.getByUid(user.uid, {contact: true }); + if (!prismaUser) { + this.httpNotFoundRequest(response, "user not found"); + return; + } + + //Hydrate user to be able to use his contact + const userHydrated = User.hydrate(prismaUser, { strategy: "excludeAll" }); + + //Check if user is whitelisted + const isWhitelisted = await this.whitelistService.getByEmail(userHydrated.contact!.email); + + //If not whitelisted, return 409 Not whitelisted + if (!isWhitelisted) { + this.httpNotWhitelisted(response); + return; + } + + await this.idNotService.updateUser(user.uid); await this.idNotService.updateOffice(user.office_uid); const payload = await this.authService.getUserJwtPayload(user.idNot); diff --git a/src/common/databases/migrations/20231220084359_whitelist/migration.sql b/src/common/databases/migrations/20231220084359_whitelist/migration.sql new file mode 100644 index 00000000..3a252b3e --- /dev/null +++ b/src/common/databases/migrations/20231220084359_whitelist/migration.sql @@ -0,0 +1,16 @@ +-- CreateTable +CREATE TABLE "whitelist" ( + "uid" TEXT NOT NULL, + "email" VARCHAR(255) NOT NULL, + "active" BOOLEAN NOT NULL DEFAULT true, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "whitelist_pkey" PRIMARY KEY ("uid") +); + +-- CreateIndex +CREATE UNIQUE INDEX "whitelist_uid_key" ON "whitelist"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "whitelist_email_key" ON "whitelist"("email"); diff --git a/src/common/databases/schema.prisma b/src/common/databases/schema.prisma index 9d72ec44..de4afe97 100644 --- a/src/common/databases/schema.prisma +++ b/src/common/databases/schema.prisma @@ -72,6 +72,15 @@ model Users { @@map("users") } +model Whitelist { + uid String @id @unique @default(uuid()) + email String @unique @db.VarChar(255) + active Boolean @default(true) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + @@map("whitelist") +} + model Offices { uid String @id @unique @default(uuid()) idNot String @unique @db.VarChar(255) diff --git a/src/common/repositories/WhitelistRepository.ts b/src/common/repositories/WhitelistRepository.ts new file mode 100644 index 00000000..5f26c087 --- /dev/null +++ b/src/common/repositories/WhitelistRepository.ts @@ -0,0 +1,39 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Prisma } from "prisma/prisma-client"; + +@Service() +export default class WhitelistRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().whitelist; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many whitelist + */ + public async findMany(query: Prisma.WhitelistFindManyArgs) { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : find unique by email + */ + public async findOneByEmail(email: string) { + return this.model.findUnique({ + where: { + email: email, + }, + }); + } + + + +} diff --git a/src/common/system/controller-pattern/BaseController.ts b/src/common/system/controller-pattern/BaseController.ts index 0e5003cc..0603c480 100644 --- a/src/common/system/controller-pattern/BaseController.ts +++ b/src/common/system/controller-pattern/BaseController.ts @@ -48,6 +48,10 @@ export default abstract class BaseController { return this.httpResponse(response, HttpCodes.FORBIDDEN, responseData); } + protected httpNotWhitelisted(response: Response, responseData: IResponseData = "Not whitelisted") { + return this.httpResponse(response, HttpCodes.VALIDATION_ERROR, responseData); + } + protected httpResponse(response: Response, httpCode: HttpCodes, responseData: IResponseData = {}) { if (responseData instanceof Error) { throw responseData; diff --git a/src/services/common/WhitelistService/WhitelistService.ts b/src/services/common/WhitelistService/WhitelistService.ts new file mode 100644 index 00000000..9e98a35e --- /dev/null +++ b/src/services/common/WhitelistService/WhitelistService.ts @@ -0,0 +1,14 @@ +import WhitelistRepository from "@Repositories/WhitelistRepository"; +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; + +@Service() +export default class WhitelistService extends BaseService { + constructor(private whitelistRepository: WhitelistRepository) { + super(); + } + + public async getByEmail(email: string): Promise { + return this.whitelistRepository.findOneByEmail(email); + } +}