.
This commit is contained in:
parent
6310944a85
commit
55b8bb8473
@ -33,8 +33,8 @@
|
||||
"typescript": "^6.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@erp/auth": "workspace:*",
|
||||
"@erp/core": "workspace:*",
|
||||
"@erp/identity": "workspace:*",
|
||||
"@repo/i18next": "workspace:*",
|
||||
"@repo/rdx-criteria": "workspace:*",
|
||||
"@repo/rdx-ddd": "workspace:*",
|
||||
|
||||
@ -27,7 +27,7 @@ export type CatalogsPublicServicesType = ReturnType<typeof buildCatalogsPublicSe
|
||||
export const catalogsAPIModule: IModuleServer = {
|
||||
name: "catalogs",
|
||||
version: "1.0.0",
|
||||
dependencies: [],
|
||||
dependencies: ["identity"],
|
||||
|
||||
/**
|
||||
* Fase de SETUP
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
export * from "./express";
|
||||
export * from "./payment-methods";
|
||||
export * from "./payment-terms";
|
||||
export * from "./tax-definitions";
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth/api";
|
||||
import { type RequestWithAuth, type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { requireIdentityTenant } from "@erp/identity/api";
|
||||
import { type NextFunction, type Request, type Response, Router } from "express";
|
||||
|
||||
import {
|
||||
@ -30,21 +30,7 @@ export const paymentMethodsRouter = (params: StartParams) => {
|
||||
|
||||
// ----------------------------------------------
|
||||
|
||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||
// 🔐 Autenticación + Tenancy para TODO el router
|
||||
router.use(
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
mockUser(req as RequestWithAuth, res, next) // Debe ir antes de las rutas protegidas
|
||||
);
|
||||
}
|
||||
|
||||
router.use([
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireAuthenticated()(req as RequestWithAuth, res, next), // Debe ir antes de las rutas protegidas
|
||||
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireCompanyContext()(req as RequestWithAuth, res, next), // Debe ir antes de las rutas protegidas
|
||||
]);
|
||||
router.use(...requireIdentityTenant(params));
|
||||
|
||||
// ----------------------------------------------
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth/api";
|
||||
import { type RequestWithAuth, type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { requireIdentityTenant } from "@erp/identity/api";
|
||||
import type { NextFunction, Request, Response } from "express";
|
||||
import { Router } from "express";
|
||||
|
||||
@ -29,18 +29,7 @@ export const paymentTermsRouter = (params: StartParams) => {
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||
router.use((req: Request, res: Response, next: NextFunction) =>
|
||||
mockUser(req as RequestWithAuth, res, next)
|
||||
);
|
||||
}
|
||||
|
||||
router.use([
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireAuthenticated()(req as RequestWithAuth, res, next),
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireCompanyContext()(req as RequestWithAuth, res, next),
|
||||
]);
|
||||
router.use(...requireIdentityTenant(params));
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth/api";
|
||||
import { type RequestWithAuth, type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { requireIdentityTenant } from "@erp/identity/api";
|
||||
import type { NextFunction, Request, Response } from "express";
|
||||
import { Router } from "express";
|
||||
|
||||
@ -29,18 +29,7 @@ export const taxDefinitionsRouter = (params: StartParams) => {
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||
router.use((req: Request, res: Response, next: NextFunction) =>
|
||||
mockUser(req as RequestWithAuth, res, next)
|
||||
);
|
||||
}
|
||||
|
||||
router.use([
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireAuthenticated()(req as RequestWithAuth, res, next),
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireCompanyContext()(req as RequestWithAuth, res, next),
|
||||
]);
|
||||
router.use(...requireIdentityTenant(params));
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth/api";
|
||||
import { type RequestWithAuth, type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { requireIdentityTenant } from "@erp/identity/api";
|
||||
import type { NextFunction, Request, Response } from "express";
|
||||
import { Router } from "express";
|
||||
|
||||
@ -29,18 +29,7 @@ export const taxRegimesRouter = (params: StartParams) => {
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||
router.use((req: Request, res: Response, next: NextFunction) =>
|
||||
mockUser(req as RequestWithAuth, res, next)
|
||||
);
|
||||
}
|
||||
|
||||
router.use([
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireAuthenticated()(req as RequestWithAuth, res, next),
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireCompanyContext()(req as RequestWithAuth, res, next),
|
||||
]);
|
||||
router.use(...requireIdentityTenant(params));
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
|
||||
@ -81,11 +81,23 @@ export const useCreateProformaController = (options?: UseCreateProformaControlle
|
||||
|
||||
const setCustomer = (customer: CustomerSelectionOption) => {
|
||||
setSelectedCustomer(customer);
|
||||
|
||||
// Necesitamos consultar todos los datos del cliente para
|
||||
// poder rellenar los campos de la proforma
|
||||
|
||||
form.setValue("customerId", customer.id, {
|
||||
shouldDirty: true,
|
||||
shouldTouch: true,
|
||||
shouldValidate: true,
|
||||
});
|
||||
|
||||
/*form.setValue("")
|
||||
|
||||
form.setValue("taxRegimeCode", customer.taxRegimeCode ?? "", {
|
||||
shouldDirty: true,
|
||||
shouldTouch: true,
|
||||
shouldValidate: true,
|
||||
});*/
|
||||
};
|
||||
|
||||
const clearCustomer = () => {
|
||||
|
||||
@ -34,9 +34,9 @@
|
||||
"typescript": "^6.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@erp/auth": "workspace:*",
|
||||
"@erp/core": "workspace:*",
|
||||
"@erp/catalogs": "workspace:*",
|
||||
"@erp/core": "workspace:*",
|
||||
"@erp/identity": "workspace:*",
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@repo/i18next": "workspace:*",
|
||||
"@repo/rdx-criteria": "workspace:*",
|
||||
|
||||
@ -10,7 +10,7 @@ export * from "./infrastructure/persistence/sequelize";
|
||||
export const customersAPIModule: IModuleServer = {
|
||||
name: "customers",
|
||||
version: "1.0.0",
|
||||
dependencies: ["catalogs"],
|
||||
dependencies: ["catalogs", "identity"],
|
||||
|
||||
/**
|
||||
* Fase de SETUP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth/api";
|
||||
import { type RequestWithAuth, type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { type StartParams, validateRequest } from "@erp/core/api";
|
||||
import { requireIdentityTenant } from "@erp/identity/api";
|
||||
import { type NextFunction, type Request, type Response, Router } from "express";
|
||||
|
||||
import {
|
||||
@ -29,21 +29,7 @@ export const customersRouter = (params: StartParams) => {
|
||||
// ----------------------------------------------
|
||||
|
||||
// 🔐 Autenticación + Tenancy para TODO el router
|
||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||
router.use(
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
mockUser(req as RequestWithAuth, res, next) // Debe ir antes de las rutas protegidas
|
||||
);
|
||||
}
|
||||
|
||||
//router.use(/*authenticateJWT(),*/ enforceTenant() /*checkTabContext*/);
|
||||
router.use([
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireAuthenticated()(req as RequestWithAuth, res, next), // Debe ir antes de las rutas protegidas
|
||||
|
||||
(req: Request, res: Response, next: NextFunction) =>
|
||||
requireCompanyContext()(req as RequestWithAuth, res, next), // Debe ir antes de las rutas protegidas
|
||||
]);
|
||||
router.use(...requireIdentityTenant(params));
|
||||
|
||||
// ----------------------------------------------
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from './build-customer-selection-option';
|
||||
export * from "./build-customer-data";
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@erp/customers/*": ["./src/*"]
|
||||
"@erp/customers/*": ["./src/*"],
|
||||
"@erp/identity/*": ["../identity/src/*"]
|
||||
},
|
||||
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
|
||||
@ -34,7 +34,9 @@
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcrypt": "^6.0.0",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
|
||||
@ -4,3 +4,4 @@ export * from "./companies";
|
||||
export * from "./company-memberships";
|
||||
export * from "./permissions";
|
||||
export * from "./roles";
|
||||
export * from "./services";
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import type { RequestHandler } from "express";
|
||||
|
||||
export type AuthenticatedOnlyMiddlewares = readonly [RequestHandler, RequestHandler];
|
||||
|
||||
export type TenantRequiredMiddlewares = readonly [RequestHandler, RequestHandler, RequestHandler];
|
||||
|
||||
export interface IIdentityAuthPublicServices {
|
||||
authenticatedOnly(): AuthenticatedOnlyMiddlewares;
|
||||
tenantRequired(): TenantRequiredMiddlewares;
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
import type { IIdentityAuthPublicServices } from "./identity-auth-public-services.interface";
|
||||
|
||||
export interface IIdentityPublicServices {
|
||||
auth: IIdentityAuthPublicServices;
|
||||
}
|
||||
2
modules/identity/src/api/application/services/index.ts
Normal file
2
modules/identity/src/api/application/services/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./identity-auth-public-services.interface";
|
||||
export * from "./identity-public-services.interface";
|
||||
@ -1,13 +1,16 @@
|
||||
import type { IModuleServer } from "@erp/core/api";
|
||||
|
||||
import type { IIdentityPublicServices } from "./application";
|
||||
export * from "./application";
|
||||
export * from "./domain";
|
||||
export * from "./infrastructure";
|
||||
|
||||
import { identityAuthRouter, models } from "./infrastructure";
|
||||
import { buildIdentityDependencies } from "./infrastructure/di";
|
||||
import { buildIdentityDependencies, buildIdentityPublicServices } from "./infrastructure/di";
|
||||
|
||||
export * from "./infrastructure/persistence/sequelize";
|
||||
export type { IIdentityAuthPublicServices, IIdentityPublicServices } from "./application";
|
||||
export type IdentityPublicServicesType = IIdentityPublicServices;
|
||||
|
||||
export const identityAPIModule: IModuleServer = {
|
||||
name: "identity",
|
||||
@ -28,8 +31,7 @@ export const identityAPIModule: IModuleServer = {
|
||||
const internal = buildIdentityDependencies(params);
|
||||
|
||||
// 2) Servicios públicos (Application Services)
|
||||
const identityServices = {};
|
||||
//const identityServices: IIdentityPublicServices = {}; //buildIdentityPublicServices(params, internal);
|
||||
const identityServices: IIdentityPublicServices = buildIdentityPublicServices(internal);
|
||||
|
||||
logger.info("🚀 Identity module dependencies registered", {
|
||||
label: this.name,
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
import type {
|
||||
IIdentityAuthPublicServices,
|
||||
IIdentityPublicServices,
|
||||
} from "../../application";
|
||||
import {
|
||||
authenticateUser,
|
||||
requireAuthenticated,
|
||||
requireCompanyContext,
|
||||
} from "../express/middlewares";
|
||||
|
||||
import type { IdentityInternalDeps } from "./identity.di";
|
||||
|
||||
class IdentityAuthPublicServices implements IIdentityAuthPublicServices {
|
||||
public constructor(
|
||||
private readonly deps: IdentityInternalDeps["auth"]["authenticateUserDependencies"]
|
||||
) {}
|
||||
|
||||
public authenticatedOnly() {
|
||||
return [authenticateUser(this.deps), requireAuthenticated()] as const;
|
||||
}
|
||||
|
||||
public tenantRequired() {
|
||||
return [
|
||||
authenticateUser(this.deps),
|
||||
requireAuthenticated(),
|
||||
requireCompanyContext(),
|
||||
] as const;
|
||||
}
|
||||
}
|
||||
|
||||
export function buildIdentityPublicServices(deps: IdentityInternalDeps): IIdentityPublicServices {
|
||||
return {
|
||||
auth: new IdentityAuthPublicServices(deps.auth.authenticateUserDependencies),
|
||||
};
|
||||
}
|
||||
@ -2,6 +2,7 @@ import { type ModuleParams, buildTransactionManager } from "@erp/core/api";
|
||||
|
||||
import {
|
||||
AccountAuthenticator,
|
||||
type IAccessTokenVerifier,
|
||||
type GetCurrentSessionUseCase,
|
||||
GetCurrentSessionUseCase as GetCurrentSessionUseCaseImpl,
|
||||
type LoginWithPasswordUseCase,
|
||||
@ -12,6 +13,7 @@ import {
|
||||
RefreshSessionUseCase as RefreshSessionUseCaseImpl,
|
||||
SessionIssuer,
|
||||
} from "../../application/authentication";
|
||||
import type { IAccountRepository } from "../../application/accounts";
|
||||
import { identityAuthenticateRequest } from "../express/middlewares";
|
||||
import {
|
||||
SequelizeAccountDomainMapper,
|
||||
@ -30,6 +32,10 @@ import {
|
||||
export type IdentityInternalDeps = {
|
||||
auth: {
|
||||
refreshTokenExpiration: string;
|
||||
authenticateUserDependencies: {
|
||||
accessTokenVerifier: IAccessTokenVerifier;
|
||||
accountRepository: IAccountRepository;
|
||||
};
|
||||
authenticateRequest: ReturnType<typeof identityAuthenticateRequest>;
|
||||
useCases: {
|
||||
loginWithPassword: () => LoginWithPasswordUseCase;
|
||||
@ -79,6 +85,10 @@ export const buildIdentityDependencies = (params: ModuleParams): IdentityInterna
|
||||
return {
|
||||
auth: {
|
||||
refreshTokenExpiration: config.auth.jwt.refreshExpiration,
|
||||
authenticateUserDependencies: {
|
||||
accessTokenVerifier,
|
||||
accountRepository,
|
||||
},
|
||||
authenticateRequest: identityAuthenticateRequest({
|
||||
accessTokenVerifier,
|
||||
accountRepository,
|
||||
|
||||
@ -1 +1,2 @@
|
||||
export * from "./identity.di";
|
||||
export * from "./identity-public-services";
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
export * from "./authenticate-user.middleware";
|
||||
export * from "./require-authenticated.middleware";
|
||||
export * from "./require-company-context.middleware";
|
||||
export * from "./require-identity-middlewares";
|
||||
export * from "./identity-authenticate-request";
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import { ExpressController, UnauthorizedApiError, type RequestWithAuth } from "@erp/core/api";
|
||||
import type { NextFunction, Response } from "express";
|
||||
import type { NextFunction, Request, Response } from "express";
|
||||
|
||||
export function requireAuthenticated() {
|
||||
return (req: RequestWithAuth, res: Response, next: NextFunction) => {
|
||||
if (!req.user) {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
if (!(req as RequestWithAuth).user) {
|
||||
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { ExpressController, ForbiddenApiError, type RequestWithAuth } from "@erp/core/api";
|
||||
import type { NextFunction, Response } from "express";
|
||||
import type { NextFunction, Request, Response } from "express";
|
||||
|
||||
export function requireCompanyContext() {
|
||||
return (req: RequestWithAuth, res: Response, next: NextFunction) => {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
/**
|
||||
* TODO: validar membership real cuando exista persistencia de CompanyMembership.
|
||||
*/
|
||||
if (!req.user?.companyId) {
|
||||
if (!(req as RequestWithAuth).user?.companyId) {
|
||||
return ExpressController.errorResponse(
|
||||
new ForbiddenApiError("Company context required"),
|
||||
req,
|
||||
@ -17,4 +17,3 @@ export function requireCompanyContext() {
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
import type { StartParams } from "@erp/core/api";
|
||||
import type { RequestHandler } from "express";
|
||||
|
||||
import type { IIdentityPublicServices } from "../../../application";
|
||||
|
||||
export function requireIdentityAuthenticated(params: StartParams): RequestHandler[] {
|
||||
const identityServices = params.getService<IIdentityPublicServices>("identity:general");
|
||||
return [...identityServices.auth.authenticatedOnly()];
|
||||
}
|
||||
|
||||
export function requireIdentityTenant(params: StartParams): RequestHandler[] {
|
||||
const identityServices = params.getService<IIdentityPublicServices>("identity:general");
|
||||
return [...identityServices.auth.tenantRequired()];
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user