From 8e13fa18ae5a550fc20774830e6eda05cbadadd4 Mon Sep 17 00:00:00 2001 From: David Arranz Date: Mon, 27 May 2024 14:01:52 +0200 Subject: [PATCH] . --- server/src/config/environments/development.ts | 20 ++++---- .../users/application/userServices.ts | 50 +++++++++++++------ .../repository/UserRepository.interface.ts | 9 +--- .../users/infrastructure/User.repository.ts | 44 +++++++--------- .../express/api/context.middleware.ts | 9 +--- server/src/infrastructure/http/server.ts | 5 ++ .../sequelize/initializeAdminUser.ts | 10 ++++ 7 files changed, 82 insertions(+), 65 deletions(-) create mode 100644 server/src/infrastructure/sequelize/initializeAdminUser.ts diff --git a/server/src/config/environments/development.ts b/server/src/config/environments/development.ts index ebc0725..c7517fb 100644 --- a/server/src/config/environments/development.ts +++ b/server/src/config/environments/development.ts @@ -1,9 +1,7 @@ module.exports = { jwt: { - secret_key: - "9d6c903873c341816995a8be0355c6f0d6d471fc6aedacf50790e9b1e49c45b3", - refresh_secret_key: - "3972dc40c69327b65352ed097419213b0b75561169dba562410b85660bb1f305", + secret_key: "9d6c903873c341816995a8be0355c6f0d6d471fc6aedacf50790e9b1e49c45b3", + refresh_secret_key: "3972dc40c69327b65352ed097419213b0b75561169dba562410b85660bb1f305", token_expiration: "7d", refresh_token_expiration: "30d", }, @@ -38,12 +36,14 @@ module.exports = { public_url: "", }, + admin: { + name: "Administrador", + email: "darranz@rodax-software.com", + password: "123456", + }, + uploads: { - imports: - process.env.UPLOAD_PATH || - "/home/rodax/Documentos/BBDD/server/uploads/imports", - documents: - process.env.UPLOAD_PATH || - "/home/rodax/Documentos/BBDD/server/uploads/documents", + imports: process.env.UPLOAD_PATH || "/home/rodax/Documentos/BBDD/server/uploads/imports", + documents: process.env.UPLOAD_PATH || "/home/rodax/Documentos/BBDD/server/uploads/documents", }, }; diff --git a/server/src/contexts/users/application/userServices.ts b/server/src/contexts/users/application/userServices.ts index ad318d5..33981a5 100644 --- a/server/src/contexts/users/application/userServices.ts +++ b/server/src/contexts/users/application/userServices.ts @@ -1,11 +1,12 @@ -import { IAdapter, RepositoryBuilder } from "@/contexts/common/domain"; +import { config } from "@/config"; +import { IAdapter, Password, RepositoryBuilder } from "@/contexts/common/domain"; import { Email, Name, UniqueID } from "@shared/contexts"; -import { IUserRepository, User } from "../domain"; +import { IUserRepository, User, UserRole } from "../domain"; export const existsUserByID = async ( id: UniqueID, adapter: IAdapter, - repository: RepositoryBuilder, + repository: RepositoryBuilder ): Promise => { return await adapter .startTransaction() @@ -15,19 +16,17 @@ export const existsUserByID = async ( export const existsUserByName = async ( name: Name, adapter: IAdapter, - repository: RepositoryBuilder, + repository: RepositoryBuilder ): Promise => { return await adapter .startTransaction() - .complete(async (t) => - repository({ transaction: t }).existsUserWithName(name), - ); + .complete(async (t) => repository({ transaction: t }).existsUserWithName(name)); }; export const findUserByID = async ( id: UniqueID, adapter: IAdapter, - repository: RepositoryBuilder, + repository: RepositoryBuilder ): Promise => { return await adapter .startTransaction() @@ -37,23 +36,42 @@ export const findUserByID = async ( export const existsUserByEmail = async ( email: Email, adapter: IAdapter, - repository: RepositoryBuilder, + repository: RepositoryBuilder ): Promise => { return await adapter .startTransaction() - .complete(async (t) => - repository({ transaction: t }).existsUserWithEmail(email), - ); + .complete(async (t) => repository({ transaction: t }).existsUserWithEmail(email)); }; export const findUserByEmail = async ( email: Email, adapter: IAdapter, - repository: RepositoryBuilder, + repository: RepositoryBuilder ): Promise => { return await adapter .startTransaction() - .complete(async (t) => - repository({ transaction: t }).findUserByEmail(email), - ); + .complete(async (t) => repository({ transaction: t }).findUserByEmail(email)); +}; + +export const initializeAdmin = async ( + adapter: IAdapter, + repository: RepositoryBuilder +) => { + return await adapter.startTransaction().complete(async (t) => { + const adminExists = await repository({ transaction: t }).existsAdminUser(); + + if (!adminExists) { + const admin = User.create( + { + name: Name.create(config.admin.name).object, + email: Email.create(config.admin.email).object, + password: Password.createFromPlainTextPassword(config.admin.password).object, + roles: [UserRole.ROLE_ADMIN], + }, + UniqueID.generateNewID().object + ).object; + await repository({ transaction: t }).create(admin); + console.log("Usuario administrador creado"); + } + }); }; diff --git a/server/src/contexts/users/domain/repository/UserRepository.interface.ts b/server/src/contexts/users/domain/repository/UserRepository.interface.ts index 7c6b21d..0127da0 100644 --- a/server/src/contexts/users/domain/repository/UserRepository.interface.ts +++ b/server/src/contexts/users/domain/repository/UserRepository.interface.ts @@ -1,11 +1,5 @@ import { IRepository } from "@/contexts/common/domain"; -import { - Email, - ICollection, - IQueryCriteria, - Name, - UniqueID, -} from "@shared/contexts"; +import { Email, ICollection, IQueryCriteria, Name, UniqueID } from "@shared/contexts"; import { User } from "../entities"; export interface IUserRepository extends IRepository { @@ -18,6 +12,7 @@ export interface IUserRepository extends IRepository { removeById(id: UniqueID): Promise; + existsAdminUser(): Promise; existsUserWithId(id: UniqueID): Promise; existsUserWithName(name: Name): Promise; existsUserWithEmail(email: Email): Promise; diff --git a/server/src/contexts/users/infrastructure/User.repository.ts b/server/src/contexts/users/infrastructure/User.repository.ts index 471e78e..07facf7 100644 --- a/server/src/contexts/users/infrastructure/User.repository.ts +++ b/server/src/contexts/users/infrastructure/User.repository.ts @@ -1,15 +1,6 @@ -import { - ISequelizeAdapter, - SequelizeRepository, -} from "@/contexts/common/infrastructure/sequelize"; -import { - Email, - ICollection, - IQueryCriteria, - Name, - UniqueID, -} from "@shared/contexts"; -import { Transaction } from "sequelize"; +import { ISequelizeAdapter, SequelizeRepository } from "@/contexts/common/infrastructure/sequelize"; +import { Email, ICollection, IQueryCriteria, Name, UniqueID } from "@shared/contexts"; +import { Op, Transaction } from "sequelize"; import { User } from "../domain"; import { IUserRepository } from "../domain/repository"; import { IUserContext } from "./User.context"; @@ -20,10 +11,7 @@ export type QueryParams = { filters: Record; }; -export class UserRepository - extends SequelizeRepository - implements IUserRepository -{ +export class UserRepository extends SequelizeRepository implements IUserRepository { protected mapper: IUserMapper; public constructor(props: { @@ -60,11 +48,7 @@ export class UserRepository } public async findUserByEmail(email: Email): Promise { - const rawUser: any = await this._getBy( - "User_Model", - "email", - email.toPrimitive(), - ); + const rawUser: any = await this._getBy("User_Model", "email", email.toPrimitive()); if (!rawUser === true) { return null; @@ -73,12 +57,10 @@ export class UserRepository return this.mapper.mapToDomain(rawUser); } - public async findAll( - queryCriteria?: IQueryCriteria, - ): Promise> { + public async findAll(queryCriteria?: IQueryCriteria): Promise> { const { rows, count } = await this._findAll( "User_Model", - queryCriteria, + queryCriteria /*{ include: [], // esto es para quitar las asociaciones al hacer la consulta }*/ @@ -91,6 +73,18 @@ export class UserRepository return this._removeById("User_Model", id); } + public async existsAdminUser(): Promise { + const _model = this._adapter.getModel("User_Model"); + + // Verificar si el usuario administrador existe + const count: number = await _model.count({ + where: { roles: { [Op.like]: ["%ROLE_ADMIN%"] } }, + transaction: this._transaction, + }); + + return Promise.resolve(Boolean(count !== 0)); + } + public async existsUserWithId(id: UniqueID): Promise { return this._exists("User_Model", "id", id.toPrimitive()); } diff --git a/server/src/infrastructure/express/api/context.middleware.ts b/server/src/infrastructure/express/api/context.middleware.ts index ab1a8d6..a442b2c 100644 --- a/server/src/infrastructure/express/api/context.middleware.ts +++ b/server/src/infrastructure/express/api/context.middleware.ts @@ -1,8 +1,3 @@ -import { RepositoryManager } from "@/contexts/common/domain"; -import { createSequelizeAdapter } from "@/contexts/common/infrastructure/sequelize"; +import { UserContext } from "@/contexts/users/infrastructure/User.context"; -export const createContextMiddleware = () => ({ - adapter: createSequelizeAdapter(), - repositoryManager: RepositoryManager.getInstance(), - services: {}, -}); +export const createContextMiddleware = () => UserContext.getInstance(); diff --git a/server/src/infrastructure/http/server.ts b/server/src/infrastructure/http/server.ts index ed7d748..574b251 100644 --- a/server/src/infrastructure/http/server.ts +++ b/server/src/infrastructure/http/server.ts @@ -9,6 +9,7 @@ import { trace } from "console"; import { config } from "../../config"; import { app } from "../express/app"; import { initLogger } from "../logger"; +import { initializeAdminUser } from "../sequelize/initializeAdminUser"; process.env.TZ = "UTC"; Settings.defaultLocale = "es-ES"; @@ -106,6 +107,10 @@ const server: http.Server = http try { //firebirdConn.sync().then(() => { sequelizeConn.sync({ force: false, alter: true }).then(() => { + // + + initializeAdminUser(); + // Launch server server.listen(currentState.server.port, () => { const now = DateTime.now(); diff --git a/server/src/infrastructure/sequelize/initializeAdminUser.ts b/server/src/infrastructure/sequelize/initializeAdminUser.ts new file mode 100644 index 0000000..0931396 --- /dev/null +++ b/server/src/infrastructure/sequelize/initializeAdminUser.ts @@ -0,0 +1,10 @@ +import { initializeAdmin } from "@/contexts/users/application/userServices"; +import { UserContext } from "@/contexts/users/infrastructure/User.context"; +import { registerUserRepository } from "@/contexts/users/infrastructure/User.repository"; + +export const initializeAdminUser = () => { + const context = UserContext.getInstance(); + registerUserRepository(context); + + initializeAdmin(context.adapter, context.repositoryManager.getRepository("User")); +};