From acbbba023c7c426b6cf0977a5388bc8b9423a75d Mon Sep 17 00:00:00 2001 From: OxSaitama Date: Wed, 21 Jun 2023 15:08:00 +0200 Subject: [PATCH] add controllers for auth --- src/app/api/idnot-user/UserInfoController.ts | 108 ++++++++++++++---- src/app/api/super-admin/RolesController.ts | 32 +++--- src/app/api/super-admin/RulesController.ts | 2 +- src/app/index.ts | 4 + src/common/config/variables/Variables.ts | 22 +++- .../20230505075245_v1/migration.sql | 8 -- .../20230505131655_v2/migration.sql | 8 -- .../20230510204321_v4/migration.sql | 9 -- .../20230511085908_v5/migration.sql | 2 - .../20230515134800_v6/migration.sql | 10 -- .../20230515140007_v6/migration.sql | 10 -- .../migration.sql | 83 +++++++++++++- .../20230621100427_v1/migration.sql | 14 +++ src/common/databases/schema.prisma | 4 +- src/common/databases/seeders/seeder.ts | 20 ++++ src/common/databases/seeders/seeder2.ts | 20 ++++ .../controller-pattern/BaseController.ts | 4 + .../system/controller-pattern/HttpCodes.ts | 1 + .../AuthService/AuthService.ts | 24 +++- 19 files changed, 285 insertions(+), 100 deletions(-) delete mode 100644 src/common/databases/migrations/20230505075245_v1/migration.sql delete mode 100644 src/common/databases/migrations/20230505131655_v2/migration.sql delete mode 100644 src/common/databases/migrations/20230510204321_v4/migration.sql delete mode 100644 src/common/databases/migrations/20230511085908_v5/migration.sql delete mode 100644 src/common/databases/migrations/20230515134800_v6/migration.sql delete mode 100644 src/common/databases/migrations/20230515140007_v6/migration.sql rename src/common/databases/migrations/{20230426144239_init => 20230621092719_init}/migration.sql (85%) create mode 100644 src/common/databases/migrations/20230621100427_v1/migration.sql diff --git a/src/app/api/idnot-user/UserInfoController.ts b/src/app/api/idnot-user/UserInfoController.ts index afd5bf22..80b6dc4a 100644 --- a/src/app/api/idnot-user/UserInfoController.ts +++ b/src/app/api/idnot-user/UserInfoController.ts @@ -1,32 +1,94 @@ import { Response, Request } from "express"; - import { Controller,Post } from "@ControllerPattern/index"; - import ApiController from "@Common/system/controller-pattern/ApiController"; - import { Service } from "typedi"; +import { Controller, Post } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import { Service } from "typedi"; import AuthService from "@Services/private-services/AuthService/AuthService"; +import UsersService from "@Services/super-admin/UsersService/UsersService"; +import User from "le-coffre-resources/dist/SuperAdmin"; +import { JwtPayload } from "jsonwebtoken"; +import { validateOrReject } from "class-validator"; //import User from "le-coffre-resources/dist/Notary"; - - @Controller() - @Service() - export default class UserInfoController extends ApiController { - constructor(private authService: AuthService) { - super(); - } - - /** - * @description Get user created from IdNot authentification - * @returns User - */ - @Post("/api/v1/idnot-user/:code") - protected async getUserInfosFromIdnot(req: Request, response: Response) { - try { - const code = req.params["code"]; - const user = await this.authService.getUserFromIdNotTokens(code!); - //success + +@Controller() +@Service() +export default class UserInfoController extends ApiController { + constructor(private authService: AuthService, private userService: UsersService) { + super(); + } + + /** + * @description Get user created from IdNot authentification + * @returns User + */ + @Post("/api/v1/idnot-user/:code") + protected async getUserInfosFromIdnot(req: Request, response: Response) { + try { + const code = req.params["code"]; + const user = await this.authService.getUserFromIdNotTokens(code!); + //success this.httpSuccess(response, user); } catch (error) { this.httpInternalError(response); return; } - } + } -} \ No newline at end of file + @Post("/api/v1/login/:idnot") + protected async login(req: Request, response: Response) { + try { + const id = req.params["idnot"]; + if (!id) throw new Error("idnot is required"); + + const users = await this.userService.get({ where: { idNot: id } , include: {contact: true, role: true, office_membership: true}}); + const user = User.hydrate(users[0]!, { strategy: "excludeAll" }); + await validateOrReject(user, { groups: ["auth"] }) + console.log(user) + const accessToken = this.authService.generateAccessToken(user); + const refreshToken = this.authService.generateRefreshToken(user); + + //success + this.httpSuccess(response, { accessToken, refreshToken }); + } catch (error) { + console.log(error); + this.httpInternalError(response); + return; + } + } + + @Post("/api/v1/refresh-token") + protected async refreshToken(req: Request, response: Response) { + try { + const authHeader = req.headers["authorization"]; + const token = authHeader && authHeader.split(" ")[1]; + + if (!token) { + this.httpBadRequest(response); + return; + } + + let accessToken; + this.authService.verifyRefreshToken(token, (err, userPayload) => { + if (err) { + this.httpUnauthorized(response); + return; + } + + const user = userPayload as JwtPayload; + console.log(userPayload) + // const user = User.hydrate(userPayload!, { strategy: "excludeAll" }); + // const user = await this.userService.getByUid(userPayload!.uid); + // const users = await this.userService.getByUid(userPayload!.uid); + delete user.iat; + delete user!.exp; + accessToken = this.authService.generateAccessToken(user); + }); + + //success + this.httpSuccess(response, accessToken); + } catch (error) { + console.log(error) + this.httpInternalError(response); + return; + } + } +} diff --git a/src/app/api/super-admin/RolesController.ts b/src/app/api/super-admin/RolesController.ts index 487511a2..d7d8bc8e 100644 --- a/src/app/api/super-admin/RolesController.ts +++ b/src/app/api/super-admin/RolesController.ts @@ -1,16 +1,16 @@ import { Response, Request } from "express"; import { Controller, Get, Post, Put } from "@ControllerPattern/index"; import ApiController from "@Common/system/controller-pattern/ApiController"; -import RulesService from "@Services/super-admin/RulesService/RulesService"; +import RolesService from "@Services/super-admin/RolesService/RolesService"; import { Service } from "typedi"; import { validateOrReject } from "class-validator"; -import { Rule } from "le-coffre-resources/dist/Notary"; -import { Rules } from "@prisma/client"; +import { Role } from "le-coffre-resources/dist/Notary"; +import { Roles } from "@prisma/client"; @Controller() @Service() -export default class RulesController extends ApiController { - constructor(private rolesService: RulesService) { +export default class RolesController extends ApiController { + constructor(private rolesService: RolesService) { super(); } @@ -27,7 +27,7 @@ export default class RulesController extends ApiController { const rolesEntities = await this.rolesService.get(query); //Hydrate ressource with prisma entity - const roles = Rule.hydrateArray(rolesEntities, { strategy: "excludeAll" }); + const roles = Role.hydrateArray(rolesEntities, { strategy: "excludeAll" }); //success this.httpSuccess(response, roles); @@ -43,17 +43,17 @@ export default class RulesController extends ApiController { @Post("/api/v1/super-admin/roles") protected async getAddresses(req: Request, response: Response) { try { - //init IRule resource with request body values - const roleEntity = Rule.hydrate(req.body); + //init IRole resource with request body values + const roleEntity = Role.hydrate(req.body); //validate role - await validateOrReject(roleEntity, { groups: ["createRule"] }); + await validateOrReject(roleEntity, { groups: ["createRole"] }); //call service to get prisma entity const roleEntityCreated = await this.rolesService.create(roleEntity); //Hydrate ressource with prisma entity - const role = Rule.hydrate(roleEntityCreated, { + const role = Role.hydrate(roleEntityCreated, { strategy: "excludeAll", }); @@ -84,17 +84,17 @@ export default class RulesController extends ApiController { return; } - //init IRule resource with request body values - const roleEntity = Rule.hydrate(req.body); + //init IRole resource with request body values + const roleEntity = Role.hydrate(req.body); //validate role - await validateOrReject(roleEntity, { groups: ["update"] }); + await validateOrReject(roleEntity, { groups: ["updateRole"] }); //call service to get prisma entity const roleEntityUpdated = await this.rolesService.update(roleEntity); //Hydrate ressource with prisma entity - const role = Rule.hydrate(roleEntityUpdated, { + const role = Role.hydrate(roleEntityUpdated, { strategy: "excludeAll", }); @@ -117,7 +117,7 @@ export default class RulesController extends ApiController { this.httpBadRequest(response, "No uid provided"); return; } - let roleEntity: Rules | null; + let roleEntity: Roles | null; //get query if (req.query["q"]) { const query = JSON.parse(req.query["q"] as string); @@ -133,7 +133,7 @@ export default class RulesController extends ApiController { } //Hydrate ressource with prisma entity - const role = Rule.hydrate(roleEntity, { strategy: "excludeAll" }); + const role = Role.hydrate(roleEntity, { strategy: "excludeAll" }); //success this.httpSuccess(response, role); diff --git a/src/app/api/super-admin/RulesController.ts b/src/app/api/super-admin/RulesController.ts index b1858c0e..53b8d9a6 100644 --- a/src/app/api/super-admin/RulesController.ts +++ b/src/app/api/super-admin/RulesController.ts @@ -88,7 +88,7 @@ export default class RulesController extends ApiController { const ruleEntity = Rule.hydrate(req.body); //validate rule - await validateOrReject(ruleEntity, { groups: ["update"] }); + await validateOrReject(ruleEntity, { groups: ["updateRule"] }); //call service to get prisma entity const ruleEntityUpdated = await this.rulesService.update(ruleEntity); diff --git a/src/app/index.ts b/src/app/index.ts index e2b0a51f..62bb1c58 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -11,6 +11,8 @@ import DocumentTypesController from "./api/super-admin/DocumentTypesController"; import IdNotUserInfoController from "./api/idnot-user/UserInfoController"; import DocumentsControllerCustomer from "./api/customer/DocumentsController"; import FilesController from "./api/super-admin/FilesController"; +import RulesController from "./api/super-admin/RolesController"; +import RolesController from "./api/super-admin/RolesController"; /** @@ -30,5 +32,7 @@ export default { Container.get(IdNotUserInfoController); Container.get(FilesController); Container.get(DocumentsControllerCustomer); + Container.get(RulesController); + Container.get(RolesController); }, }; diff --git a/src/common/config/variables/Variables.ts b/src/common/config/variables/Variables.ts index bc20851c..95a8a427 100644 --- a/src/common/config/variables/Variables.ts +++ b/src/common/config/variables/Variables.ts @@ -54,6 +54,12 @@ export class BackendVariables { @IsNotEmpty() public readonly PINATA_GATEWAY!: string; + @IsNotEmpty() + public readonly ACCESS_TOKEN_SECRET!: string; + + @IsNotEmpty() + public readonly REFRESH_TOKEN_SECRET!: string; + public constructor() { dotenv.config(); this.DATABASE_PORT = process.env["DATABASE_PORT"]!; @@ -72,9 +78,21 @@ export class BackendVariables { this.PINATA_API_KEY = process.env["PINATA_API_KEY"]!; this.PINATA_API_SECRET = process.env["PINATA_API_SECRET"]!; this.PINATA_GATEWAY = process.env["PINATA_GATEWAY"]!; + this.ACCESS_TOKEN_SECRET = process.env["ACCESS_TOKEN_SECRET"]!; + this.REFRESH_TOKEN_SECRET = process.env["REFRESH_TOKEN_SECRET"]!; } - public async validate() { - await validateOrReject(this); + public async validate(groups?: string[]) { + const validationOptions = groups ? { groups } : undefined; + + try { + await validateOrReject(this, validationOptions); + } + catch(error) { + if(process.env["NODE_ENV"] === "development") { + throw error; + } + throw new Error("Some env variables are required!"); + } return this; } } diff --git a/src/common/databases/migrations/20230505075245_v1/migration.sql b/src/common/databases/migrations/20230505075245_v1/migration.sql deleted file mode 100644 index c212eab0..00000000 --- a/src/common/databases/migrations/20230505075245_v1/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - Warnings: - - - Added the required column `iv` to the `files` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "files" ADD COLUMN "iv" VARCHAR(255) NOT NULL; diff --git a/src/common/databases/migrations/20230505131655_v2/migration.sql b/src/common/databases/migrations/20230505131655_v2/migration.sql deleted file mode 100644 index a7f5aaa6..00000000 --- a/src/common/databases/migrations/20230505131655_v2/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - Warnings: - - - Added the required column `file_name` to the `files` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "files" ADD COLUMN "file_name" VARCHAR(255) NOT NULL; diff --git a/src/common/databases/migrations/20230510204321_v4/migration.sql b/src/common/databases/migrations/20230510204321_v4/migration.sql deleted file mode 100644 index 463c9e19..00000000 --- a/src/common/databases/migrations/20230510204321_v4/migration.sql +++ /dev/null @@ -1,9 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `iv` on the `files` table. All the data in the column will be lost. - -*/ --- AlterTable -ALTER TABLE "files" DROP COLUMN "iv", -ADD COLUMN "key" VARCHAR(255); diff --git a/src/common/databases/migrations/20230511085908_v5/migration.sql b/src/common/databases/migrations/20230511085908_v5/migration.sql deleted file mode 100644 index a5b3abcb..00000000 --- a/src/common/databases/migrations/20230511085908_v5/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "files" ADD COLUMN "archived_at" TIMESTAMP(3); diff --git a/src/common/databases/migrations/20230515134800_v6/migration.sql b/src/common/databases/migrations/20230515134800_v6/migration.sql deleted file mode 100644 index efaf46c5..00000000 --- a/src/common/databases/migrations/20230515134800_v6/migration.sql +++ /dev/null @@ -1,10 +0,0 @@ -/* - Warnings: - - - Added the required column `mimetype` to the `files` table without a default value. This is not possible if the table is not empty. - - Added the required column `size` to the `files` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "files" ADD COLUMN "mimetype" VARCHAR(255) NOT NULL, -ADD COLUMN "size" INTEGER NOT NULL; diff --git a/src/common/databases/migrations/20230515140007_v6/migration.sql b/src/common/databases/migrations/20230515140007_v6/migration.sql deleted file mode 100644 index efaf46c5..00000000 --- a/src/common/databases/migrations/20230515140007_v6/migration.sql +++ /dev/null @@ -1,10 +0,0 @@ -/* - Warnings: - - - Added the required column `mimetype` to the `files` table without a default value. This is not possible if the table is not empty. - - Added the required column `size` to the `files` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "files" ADD COLUMN "mimetype" VARCHAR(255) NOT NULL, -ADD COLUMN "size" INTEGER NOT NULL; diff --git a/src/common/databases/migrations/20230426144239_init/migration.sql b/src/common/databases/migrations/20230621092719_init/migration.sql similarity index 85% rename from src/common/databases/migrations/20230426144239_init/migration.sql rename to src/common/databases/migrations/20230621092719_init/migration.sql index d017a9c4..f8237a5c 100644 --- a/src/common/databases/migrations/20230426144239_init/migration.sql +++ b/src/common/databases/migrations/20230621092719_init/migration.sql @@ -35,9 +35,9 @@ CREATE TABLE "contacts" ( "last_name" VARCHAR(255) NOT NULL, "email" VARCHAR(255) NOT NULL, "phone_number" VARCHAR(50), - "cell_phone_number" VARCHAR(50), + "cell_phone_number" VARCHAR(50) NOT NULL, "civility" "ECivility" NOT NULL DEFAULT 'MALE', - "address_uid" VARCHAR(255) NOT NULL, + "address_uid" VARCHAR(255), "birthdate" TIMESTAMP(3), "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3), @@ -50,6 +50,7 @@ CREATE TABLE "users" ( "uid" TEXT NOT NULL, "idNot" VARCHAR(255) NOT NULL, "contact_uid" VARCHAR(255) NOT NULL, + "roles_uid" TEXT NOT NULL, "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3), "office_uid" VARCHAR(255) NOT NULL, @@ -174,6 +175,11 @@ CREATE TABLE "files" ( "uid" TEXT NOT NULL, "document_uid" VARCHAR(255) NOT NULL, "file_path" VARCHAR(255) NOT NULL, + "file_name" VARCHAR(255) NOT NULL, + "mimetype" VARCHAR(255) NOT NULL, + "size" INTEGER NOT NULL, + "archived_at" TIMESTAMP(3), + "key" VARCHAR(255), "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3), @@ -249,6 +255,50 @@ CREATE TABLE "deed_type_has_document_types" ( CONSTRAINT "deed_type_has_document_types_pkey" PRIMARY KEY ("uid") ); +-- CreateTable +CREATE TABLE "roles" ( + "uid" TEXT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "roles_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "rules" ( + "uid" TEXT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + "role_has_rules_uid" TEXT, + "office_role_has_rules_uid" TEXT, + + CONSTRAINT "rules_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "role_has_rules" ( + "uid" TEXT NOT NULL, + "role_uid" VARCHAR(255) NOT NULL, + "rule_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "role_has_rules_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "office_role_has_rules" ( + "uid" TEXT NOT NULL, + "role_uid" VARCHAR(255) NOT NULL, + "rule_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "office_role_has_rules_pkey" PRIMARY KEY ("uid") +); + -- CreateIndex CREATE UNIQUE INDEX "addresses_uid_key" ON "addresses"("uid"); @@ -366,12 +416,27 @@ CREATE UNIQUE INDEX "deed_type_has_document_types_uid_key" ON "deed_type_has_doc -- CreateIndex CREATE UNIQUE INDEX "deed_type_has_document_types_deed_type_uid_document_type_ui_key" ON "deed_type_has_document_types"("deed_type_uid", "document_type_uid"); +-- CreateIndex +CREATE UNIQUE INDEX "roles_uid_key" ON "roles"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "rules_uid_key" ON "rules"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "role_has_rules_uid_key" ON "role_has_rules"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_role_has_rules_uid_key" ON "office_role_has_rules"("uid"); + -- AddForeignKey ALTER TABLE "contacts" ADD CONSTRAINT "contacts_address_uid_fkey" FOREIGN KEY ("address_uid") REFERENCES "addresses"("uid") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "users" ADD CONSTRAINT "users_contact_uid_fkey" FOREIGN KEY ("contact_uid") REFERENCES "contacts"("uid") ON DELETE CASCADE ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "users" ADD CONSTRAINT "users_roles_uid_fkey" FOREIGN KEY ("roles_uid") REFERENCES "roles"("uid") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "users" ADD CONSTRAINT "users_office_uid_fkey" FOREIGN KEY ("office_uid") REFERENCES "offices"("uid") ON DELETE CASCADE ON UPDATE CASCADE; @@ -444,6 +509,14 @@ ALTER TABLE "deed_type_has_document_types" ADD CONSTRAINT "deed_type_has_documen -- AddForeignKey ALTER TABLE "deed_type_has_document_types" ADD CONSTRAINT "deed_type_has_document_types_deed_type_uid_fkey" FOREIGN KEY ("deed_type_uid") REFERENCES "deed_types"("uid") ON DELETE CASCADE ON UPDATE CASCADE; --- AlterTable -ALTER TABLE "contacts" ALTER COLUMN "cell_phone_number" SET NOT NULL, -ALTER COLUMN "address_uid" DROP NOT NULL; \ No newline at end of file +-- AddForeignKey +ALTER TABLE "rules" ADD CONSTRAINT "rules_role_has_rules_uid_fkey" FOREIGN KEY ("role_has_rules_uid") REFERENCES "role_has_rules"("uid") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "rules" ADD CONSTRAINT "rules_office_role_has_rules_uid_fkey" FOREIGN KEY ("office_role_has_rules_uid") REFERENCES "office_role_has_rules"("uid") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "role_has_rules" ADD CONSTRAINT "role_has_rules_role_uid_fkey" FOREIGN KEY ("role_uid") REFERENCES "roles"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "office_role_has_rules" ADD CONSTRAINT "office_role_has_rules_role_uid_fkey" FOREIGN KEY ("role_uid") REFERENCES "roles"("uid") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/common/databases/migrations/20230621100427_v1/migration.sql b/src/common/databases/migrations/20230621100427_v1/migration.sql new file mode 100644 index 00000000..be549452 --- /dev/null +++ b/src/common/databases/migrations/20230621100427_v1/migration.sql @@ -0,0 +1,14 @@ +/* + Warnings: + + - You are about to alter the column `roles_uid` on the `users` table. The data in that column could be lost. The data in that column will be cast from `Text` to `VarChar(255)`. + +*/ +-- DropForeignKey +ALTER TABLE "users" DROP CONSTRAINT "users_roles_uid_fkey"; + +-- AlterTable +ALTER TABLE "users" ALTER COLUMN "roles_uid" SET DATA TYPE VARCHAR(255); + +-- AddForeignKey +ALTER TABLE "users" ADD CONSTRAINT "users_roles_uid_fkey" FOREIGN KEY ("roles_uid") REFERENCES "roles"("uid") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/src/common/databases/schema.prisma b/src/common/databases/schema.prisma index 63f8da27..1208df65 100644 --- a/src/common/databases/schema.prisma +++ b/src/common/databases/schema.prisma @@ -54,8 +54,8 @@ model Users { idNot String @unique @db.VarChar(255) contact Contacts @relation(fields: [contact_uid], references: [uid], onDelete: Cascade) contact_uid String @unique @db.VarChar(255) - role Roles @relation(fields: [roles_uid], references: [uid]) - roles_uid String + role Roles @relation(fields: [roles_uid], references: [uid], onDelete: Cascade) + roles_uid String @db.VarChar(255) created_at DateTime? @default(now()) updated_at DateTime? @updatedAt office_membership Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade) diff --git a/src/common/databases/seeders/seeder.ts b/src/common/databases/seeders/seeder.ts index 3210ca98..c8eb63f8 100644 --- a/src/common/databases/seeders/seeder.ts +++ b/src/common/databases/seeders/seeder.ts @@ -19,6 +19,7 @@ import { ECivility, ECustomerStatus, PrismaClient, + Roles, } from "@prisma/client"; (async () => { @@ -226,6 +227,21 @@ import { }, ]; + const roles: Roles[] = [ + { + uid: uidRole1, + name: 'super-admin', + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidRole2, + name: 'admin', + created_at: new Date(), + updated_at: new Date(), + } + ]; + const users: Users[] = [ { uid: uidUser1, @@ -532,6 +548,10 @@ import { await prisma.offices.create({ data: office }); } + for (const role of roles) { + await prisma.roles.create({ data: role }); + } + for (const user of users) { await prisma.users.create({ data: user }); } diff --git a/src/common/databases/seeders/seeder2.ts b/src/common/databases/seeders/seeder2.ts index 248f04f7..f76f8cde 100644 --- a/src/common/databases/seeders/seeder2.ts +++ b/src/common/databases/seeders/seeder2.ts @@ -17,6 +17,7 @@ import { ECivility, ECustomerStatus, PrismaClient, + Roles, } from "@prisma/client"; (async () => { @@ -788,6 +789,21 @@ import { } ]; + const roles: Roles[] = [ + { + uid: uidRole1, + name: 'super-admin', + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidRole2, + name: 'admin', + created_at: new Date(), + updated_at: new Date(), + } + ]; + const users: Users[] = [ { uid: uidUser1, @@ -1848,6 +1864,10 @@ import { await prisma.offices.create({ data: office }); } + for (const role of roles) { + await prisma.roles.create({ data: role }); + } + for (const user of users) { await prisma.users.create({ data: user }); } diff --git a/src/common/system/controller-pattern/BaseController.ts b/src/common/system/controller-pattern/BaseController.ts index edd1af03..39bd4be7 100644 --- a/src/common/system/controller-pattern/BaseController.ts +++ b/src/common/system/controller-pattern/BaseController.ts @@ -32,6 +32,10 @@ export default abstract class BaseController { return this.httpResponse(response, HttpCodes.INTERNAL_ERROR, responseData); } + protected httpUnauthorized(response: Response, responseData: IResponseData = "http Unauthorized Request") { + return this.httpResponse(response, HttpCodes.UNAUTHORIZED, responseData); + } + protected httpNotImplemented(response: Response, responseData: IResponseData = "Not implemented") { return this.httpResponse(response, HttpCodes.NOT_IMPLEMENTED, responseData); } diff --git a/src/common/system/controller-pattern/HttpCodes.ts b/src/common/system/controller-pattern/HttpCodes.ts index 2d6d92c5..648c30b1 100644 --- a/src/common/system/controller-pattern/HttpCodes.ts +++ b/src/common/system/controller-pattern/HttpCodes.ts @@ -7,5 +7,6 @@ enum HttpCodes { UNKNOWN_ERROR = 520, NOT_IMPLEMENTED = 501, NOT_FOUND = 404, + UNAUTHORIZED = 401, } export default HttpCodes; diff --git a/src/services/private-services/AuthService/AuthService.ts b/src/services/private-services/AuthService/AuthService.ts index ab528ec4..e156a052 100644 --- a/src/services/private-services/AuthService/AuthService.ts +++ b/src/services/private-services/AuthService/AuthService.ts @@ -1,8 +1,9 @@ -import jwt from "jsonwebtoken"; +import jwt, { VerifyCallback } from "jsonwebtoken"; import BaseService from "@Services/BaseService"; import "reflect-metadata"; import { BackendVariables } from "@Common/config/variables/Variables"; -import Container, { Service } from "typedi"; +import { Service } from "typedi"; +//import User from "le-coffre-resources/dist/Notary"; type IdNotTokens = { access_token: string; @@ -11,8 +12,7 @@ type IdNotTokens = { @Service() export default class AuthService extends BaseService { - protected readonly variables = Container.get(BackendVariables); - private constructor() { + private constructor(protected variables: BackendVariables) { super(); } @@ -50,4 +50,20 @@ export default class AuthService extends BaseService { throw new Error(); } } + + public generateAccessToken(user: any) { + return jwt.sign({...user}, this.variables.ACCESS_TOKEN_SECRET, { expiresIn: "15m" }); + } + + public generateRefreshToken(user: any) { + return jwt.sign({...user}, this.variables.REFRESH_TOKEN_SECRET, { expiresIn: "1h" }); + } + + public verifyAccessToken(token: string, callback?: VerifyCallback) { + return jwt.verify(token, this.variables.ACCESS_TOKEN_SECRET, callback); + } + + public verifyRefreshToken(token: string, callback?: VerifyCallback) { + return jwt.verify(token, this.variables.REFRESH_TOKEN_SECRET, callback); + } }