@fiado/type-kit 3.293.0 → 3.294.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_test_/unit/platformRbac/enums/__snapshots__/permissionBits.test.ts.snap +6 -1
- package/bin/benefitCenter/enums/BenefitFlowEnum.d.ts +11 -0
- package/bin/benefitCenter/enums/BenefitFlowEnum.js +15 -0
- package/bin/loanConfig/enums/ModifiableByRoleEnum.d.ts +11 -0
- package/bin/loanConfig/enums/ModifiableByRoleEnum.js +15 -0
- package/bin/places/dtos/CashInFeeDto.d.ts +17 -0
- package/bin/places/dtos/CashInFeeDto.js +12 -0
- package/bin/platformRbac/dtos/CreateIntegrationRequest.d.ts +21 -0
- package/bin/platformRbac/dtos/CreateIntegrationRequest.js +57 -0
- package/bin/platformRbac/dtos/IntegrationKeyResponse.d.ts +39 -0
- package/bin/platformRbac/dtos/IntegrationKeyResponse.js +2 -0
- package/bin/platformRbac/dtos/IntegrationResponse.d.ts +25 -0
- package/bin/platformRbac/dtos/IntegrationResponse.js +2 -0
- package/bin/platformRbac/dtos/IntegrationWhoamiResponse.d.ts +21 -0
- package/bin/platformRbac/dtos/IntegrationWhoamiResponse.js +2 -0
- package/bin/platformRbac/dtos/ResendOtpRequest.d.ts +22 -0
- package/bin/platformRbac/dtos/ResendOtpRequest.js +36 -0
- package/bin/platformRbac/dtos/ResendSelfRegisterOtpRequest.d.ts +11 -0
- package/bin/platformRbac/dtos/ResendSelfRegisterOtpRequest.js +36 -0
- package/bin/platformRbac/dtos/UpdateIntegrationRequest.d.ts +18 -0
- package/bin/platformRbac/dtos/UpdateIntegrationRequest.js +51 -0
- package/bin/platformRbac/enums/Permission.d.ts +6 -1
- package/bin/platformRbac/enums/Permission.js +22 -0
- package/bin/platformRbac/index.d.ts +5 -0
- package/bin/platformRbac/index.js +4 -0
- package/package.json +1 -1
- package/src/platformRbac/dtos/CreateIntegrationRequest.ts +24 -0
- package/src/platformRbac/dtos/IntegrationKeyResponse.ts +41 -0
- package/src/platformRbac/dtos/IntegrationResponse.ts +26 -0
- package/src/platformRbac/dtos/IntegrationWhoamiResponse.ts +21 -0
- package/src/platformRbac/dtos/UpdateIntegrationRequest.ts +21 -0
- package/src/platformRbac/enums/Permission.ts +24 -0
- package/src/platformRbac/index.ts +12 -0
- package/bin/loanCredit/dtos/requests/UpdateActivationChecklistRequest.d.ts +0 -11
- package/bin/loanCredit/dtos/requests/UpdateActivationChecklistRequest.js +0 -46
- package/bin/loanCredit/enums/ClientLevelEnum.d.ts +0 -11
- package/bin/loanCredit/enums/ClientLevelEnum.js +0 -15
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
|
2
2
|
|
|
3
|
-
exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `
|
|
3
|
+
exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `3833769424`;
|
|
4
4
|
|
|
5
5
|
exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe ante cualquier reorden/inserción) 1`] = `
|
|
6
6
|
[
|
|
@@ -90,5 +90,10 @@ exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe an
|
|
|
90
90
|
"level3.role.assign",
|
|
91
91
|
"level3.role.revoke",
|
|
92
92
|
"level3.audit.view",
|
|
93
|
+
"platform.integration.view",
|
|
94
|
+
"platform.integration.manage",
|
|
95
|
+
"platform.integration.key.issue",
|
|
96
|
+
"platform.integration.key.revoke",
|
|
97
|
+
"tenant.integration.diagnostic",
|
|
93
98
|
]
|
|
94
99
|
`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare enum BenefitFlowEnum {
|
|
2
|
+
TOPUPS = "TOPUPS",
|
|
3
|
+
BILL_PAYMENT = "BILL_PAYMENT",
|
|
4
|
+
CREDIT = "CREDIT",
|
|
5
|
+
INSURANCE = "INSURANCE",
|
|
6
|
+
DONATION = "DONATION",
|
|
7
|
+
PHARMACY = "PHARMACY",
|
|
8
|
+
REMITTANCE = "REMITTANCE",
|
|
9
|
+
/** Fondeo de wallet PCF con efectivo via provider externo (Equality/Passport, OpenPay, …) — spec 13. */
|
|
10
|
+
WALLET_FUNDING = "WALLET_FUNDING"
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BenefitFlowEnum = void 0;
|
|
4
|
+
var BenefitFlowEnum;
|
|
5
|
+
(function (BenefitFlowEnum) {
|
|
6
|
+
BenefitFlowEnum["TOPUPS"] = "TOPUPS";
|
|
7
|
+
BenefitFlowEnum["BILL_PAYMENT"] = "BILL_PAYMENT";
|
|
8
|
+
BenefitFlowEnum["CREDIT"] = "CREDIT";
|
|
9
|
+
BenefitFlowEnum["INSURANCE"] = "INSURANCE";
|
|
10
|
+
BenefitFlowEnum["DONATION"] = "DONATION";
|
|
11
|
+
BenefitFlowEnum["PHARMACY"] = "PHARMACY";
|
|
12
|
+
BenefitFlowEnum["REMITTANCE"] = "REMITTANCE";
|
|
13
|
+
/** Fondeo de wallet PCF con efectivo via provider externo (Equality/Passport, OpenPay, …) — spec 13. */
|
|
14
|
+
BenefitFlowEnum["WALLET_FUNDING"] = "WALLET_FUNDING";
|
|
15
|
+
})(BenefitFlowEnum || (exports.BenefitFlowEnum = BenefitFlowEnum = {}));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rol RBAC mínimo que puede modificar un parámetro (RBAC a nivel de parámetro, modelo-datos §8).
|
|
3
|
+
* `retailer_admin` = "Admin VentasLuga" de M6 §8. Valores = identificadores de rol de RBAC F0.
|
|
4
|
+
* TD-004: confirmar mapeo super_admin ↔ platform_super_admin con el naming real de F0.
|
|
5
|
+
* @enum {string}
|
|
6
|
+
*/
|
|
7
|
+
export declare enum ModifiableByRoleEnum {
|
|
8
|
+
SUPER_ADMIN = "super_admin",
|
|
9
|
+
SOFOM_ADMIN = "sofom_admin",
|
|
10
|
+
RETAILER_ADMIN = "retailer_admin"
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModifiableByRoleEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Rol RBAC mínimo que puede modificar un parámetro (RBAC a nivel de parámetro, modelo-datos §8).
|
|
6
|
+
* `retailer_admin` = "Admin VentasLuga" de M6 §8. Valores = identificadores de rol de RBAC F0.
|
|
7
|
+
* TD-004: confirmar mapeo super_admin ↔ platform_super_admin con el naming real de F0.
|
|
8
|
+
* @enum {string}
|
|
9
|
+
*/
|
|
10
|
+
var ModifiableByRoleEnum;
|
|
11
|
+
(function (ModifiableByRoleEnum) {
|
|
12
|
+
ModifiableByRoleEnum["SUPER_ADMIN"] = "super_admin";
|
|
13
|
+
ModifiableByRoleEnum["SOFOM_ADMIN"] = "sofom_admin";
|
|
14
|
+
ModifiableByRoleEnum["RETAILER_ADMIN"] = "retailer_admin";
|
|
15
|
+
})(ModifiableByRoleEnum || (exports.ModifiableByRoleEnum = ModifiableByRoleEnum = {}));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CurrencyId } from '../../currency/enums/CurrencyId';
|
|
2
|
+
/**
|
|
3
|
+
* Comisión que cobra un punto de cash-in (lo que el lambda MUESTRA, no cobra).
|
|
4
|
+
* - GreenDot (US): representativo por cadena → `fixed` + `cap` (cada tienda cobra hasta el tope).
|
|
5
|
+
* - Passport (MX): por red → `fixed` + `percentage`.
|
|
6
|
+
* Response DTO — sin decoradores de validación.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CashInFeeDto {
|
|
9
|
+
/** Comisión fija, en la moneda del país. */
|
|
10
|
+
fixed?: number;
|
|
11
|
+
/** Porcentaje del monto depositado (0–100). */
|
|
12
|
+
percentage?: number;
|
|
13
|
+
/** Tope máximo de comisión (GreenDot: el asociado cobra hasta este cap). */
|
|
14
|
+
cap?: number;
|
|
15
|
+
/** Moneda del fee: USD (GreenDot) | MXN (Passport). */
|
|
16
|
+
currency: CurrencyId;
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CashInFeeDto = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Comisión que cobra un punto de cash-in (lo que el lambda MUESTRA, no cobra).
|
|
6
|
+
* - GreenDot (US): representativo por cadena → `fixed` + `cap` (cada tienda cobra hasta el tope).
|
|
7
|
+
* - Passport (MX): por red → `fixed` + `percentage`.
|
|
8
|
+
* Response DTO — sin decoradores de validación.
|
|
9
|
+
*/
|
|
10
|
+
class CashInFeeDto {
|
|
11
|
+
}
|
|
12
|
+
exports.CashInFeeDto = CashInFeeDto;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body del POST /platform/tenants/{tenantId}/integrations. `tenantId` viaja en el path.
|
|
3
|
+
*
|
|
4
|
+
* Da de alta una integración M2M con un socio externo (DEC-RBAC-120/121). Los datos son del tenant
|
|
5
|
+
* pero **solo un usuario de plataforma** puede crearla.
|
|
6
|
+
*
|
|
7
|
+
* `roleId` es un rol del silo del tenant, elegido de los que ya existen — no se siembra uno
|
|
8
|
+
* especial. Está sujeto a las guardas anti-escalada: no puede contener permisos de administración
|
|
9
|
+
* de integraciones ni calcular scope PLATFORM (DEC-RBAC-122/126).
|
|
10
|
+
*
|
|
11
|
+
* `ipAllowlist` es OPCIONAL y su semántica es permisiva (spec §5): ausente, vacía o `['*']` ⇒ sin
|
|
12
|
+
* restricción de IP. Que se pueda apagar es deliberado; que se apague en silencio, no — por eso la
|
|
13
|
+
* pantalla marca las integraciones sin restricción.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CreateIntegrationRequest {
|
|
16
|
+
displayName: string;
|
|
17
|
+
roleId: string;
|
|
18
|
+
ipAllowlist?: string[];
|
|
19
|
+
/** cognitoSub del operador real (audit + grantedBy del assignment). */
|
|
20
|
+
createdBy: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CreateIntegrationRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* Body del POST /platform/tenants/{tenantId}/integrations. `tenantId` viaja en el path.
|
|
17
|
+
*
|
|
18
|
+
* Da de alta una integración M2M con un socio externo (DEC-RBAC-120/121). Los datos son del tenant
|
|
19
|
+
* pero **solo un usuario de plataforma** puede crearla.
|
|
20
|
+
*
|
|
21
|
+
* `roleId` es un rol del silo del tenant, elegido de los que ya existen — no se siembra uno
|
|
22
|
+
* especial. Está sujeto a las guardas anti-escalada: no puede contener permisos de administración
|
|
23
|
+
* de integraciones ni calcular scope PLATFORM (DEC-RBAC-122/126).
|
|
24
|
+
*
|
|
25
|
+
* `ipAllowlist` es OPCIONAL y su semántica es permisiva (spec §5): ausente, vacía o `['*']` ⇒ sin
|
|
26
|
+
* restricción de IP. Que se pueda apagar es deliberado; que se apague en silencio, no — por eso la
|
|
27
|
+
* pantalla marca las integraciones sin restricción.
|
|
28
|
+
*/
|
|
29
|
+
class CreateIntegrationRequest {
|
|
30
|
+
}
|
|
31
|
+
exports.CreateIntegrationRequest = CreateIntegrationRequest;
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, class_transformer_1.Expose)(),
|
|
34
|
+
(0, class_validator_1.IsString)(),
|
|
35
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
36
|
+
__metadata("design:type", String)
|
|
37
|
+
], CreateIntegrationRequest.prototype, "displayName", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
(0, class_transformer_1.Expose)(),
|
|
40
|
+
(0, class_validator_1.IsString)(),
|
|
41
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
42
|
+
__metadata("design:type", String)
|
|
43
|
+
], CreateIntegrationRequest.prototype, "roleId", void 0);
|
|
44
|
+
__decorate([
|
|
45
|
+
(0, class_transformer_1.Expose)(),
|
|
46
|
+
(0, class_validator_1.IsOptional)(),
|
|
47
|
+
(0, class_validator_1.IsArray)(),
|
|
48
|
+
(0, class_validator_1.ArrayNotEmpty)(),
|
|
49
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
50
|
+
__metadata("design:type", Array)
|
|
51
|
+
], CreateIntegrationRequest.prototype, "ipAllowlist", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, class_transformer_1.Expose)(),
|
|
54
|
+
(0, class_validator_1.IsString)(),
|
|
55
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
56
|
+
__metadata("design:type", String)
|
|
57
|
+
], CreateIntegrationRequest.prototype, "createdBy", void 0);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estado de una llave. NO existe `ROTATING`: rotar es emitir una segunda llave y revocar la vieja,
|
|
3
|
+
* con las dos activas mientras dura la migración del socio.
|
|
4
|
+
*/
|
|
5
|
+
export type IntegrationKeyStatusValue = 'ACTIVE' | 'REVOKED';
|
|
6
|
+
/**
|
|
7
|
+
* Una llave, tal como la devuelve el listado.
|
|
8
|
+
*
|
|
9
|
+
* 🔴 **NUNCA lleva el secreto ni el `secretHash`.** El secreto en claro se devuelve exactamente una
|
|
10
|
+
* vez, en la respuesta del POST que lo emite (`IssueIntegrationKeyResponse`), y no existe ningún
|
|
11
|
+
* endpoint que lo lea de vuelta.
|
|
12
|
+
*
|
|
13
|
+
* `lastUsedAt` y `lastUsedIp` los escribe el authorizer W5, con throttle: sirven para detectar una
|
|
14
|
+
* integración que dejó de llamar, que es uno de los dos incidentes clásicos de un canal M2M.
|
|
15
|
+
*/
|
|
16
|
+
export interface IntegrationKeyResponse {
|
|
17
|
+
keyId: string;
|
|
18
|
+
integrationId: string;
|
|
19
|
+
status: IntegrationKeyStatusValue;
|
|
20
|
+
/** epoch ms. Ausente = no vence. */
|
|
21
|
+
expiresAt?: number;
|
|
22
|
+
lastUsedAt?: number;
|
|
23
|
+
lastUsedIp?: string;
|
|
24
|
+
createdAt: number;
|
|
25
|
+
createdBy?: string;
|
|
26
|
+
revokedAt?: number;
|
|
27
|
+
revokedBy?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Respuesta del POST que emite una llave. **El único lugar de todo el sistema donde el secreto
|
|
31
|
+
* viaja en claro.**
|
|
32
|
+
*
|
|
33
|
+
* Quien lo consuma tiene que mostrarlo una sola vez y no persistirlo: no hay forma de recuperarlo
|
|
34
|
+
* después, porque en base solo queda su hash. Si se pierde, se emite otra llave.
|
|
35
|
+
*/
|
|
36
|
+
export interface IssueIntegrationKeyResponse extends IntegrationKeyResponse {
|
|
37
|
+
/** `fdo_sk.<keyId>.<secreto>` — se muestra UNA vez y no se vuelve a poder leer. */
|
|
38
|
+
token: string;
|
|
39
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Estado de una integración. Suspender corta TODAS sus llaves de una. */
|
|
2
|
+
export type IntegrationStatusValue = 'ACTIVE' | 'SUSPENDED';
|
|
3
|
+
/**
|
|
4
|
+
* Una integración, tal como la devuelven el GET de detalle y el listado.
|
|
5
|
+
*
|
|
6
|
+
* NO lleva nada del secreto de sus llaves — ni el valor ni el hash. Para eso está
|
|
7
|
+
* `IntegrationKeyResponse`, que tampoco los lleva.
|
|
8
|
+
*/
|
|
9
|
+
export interface IntegrationResponse {
|
|
10
|
+
integrationId: string;
|
|
11
|
+
tenantId: string;
|
|
12
|
+
displayName: string;
|
|
13
|
+
status: IntegrationStatusValue;
|
|
14
|
+
/** Rol del silo que porta esta integración. */
|
|
15
|
+
roleId: string;
|
|
16
|
+
/**
|
|
17
|
+
* CIDRs permitidos. Vacío o `['*']` ⇒ **sin restricción de IP** (spec §5).
|
|
18
|
+
* El front lo marca visiblemente en la lista: la protección se puede apagar, pero no en silencio.
|
|
19
|
+
*/
|
|
20
|
+
ipAllowlist: string[];
|
|
21
|
+
createdAt: number;
|
|
22
|
+
updatedAt: number;
|
|
23
|
+
createdBy?: string;
|
|
24
|
+
updatedBy?: string;
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Respuesta del endpoint de diagnóstico del authorizer W5.
|
|
3
|
+
*
|
|
4
|
+
* Devuelve **el principal ya resuelto**, no un "ok". Eso es lo que lo hace útil como prueba de la
|
|
5
|
+
* cadena completa: no verifica que el request pase, sino que haya resuelto como quien debía —
|
|
6
|
+
* con el tenant correcto y con los permisos que su rol otorga.
|
|
7
|
+
*
|
|
8
|
+
* 🔴 Endpoint TEMPORAL, solo dev: expone la lista de permisos del principal. Se saca antes de
|
|
9
|
+
* producción (el permiso `tenant.integration.diagnostic` en cambio se queda, marcado deprecado:
|
|
10
|
+
* quitarlo del enum rompería la cobertura bidireccional del catálogo y dejaría
|
|
11
|
+
* `UnknownPermissionError` en cualquier rol ya sembrado con él).
|
|
12
|
+
*/
|
|
13
|
+
export interface IntegrationWhoamiResponse {
|
|
14
|
+
principalType: 'INTEGRATION';
|
|
15
|
+
/** Con prefijo `INT#`. */
|
|
16
|
+
principalId: string;
|
|
17
|
+
integrationId: string;
|
|
18
|
+
tenantId: string;
|
|
19
|
+
/** Los permisos que resolvió el RBAC para este principal — el punto de la prueba. */
|
|
20
|
+
permissions: string[];
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MfaMethodEnum } from '../enums/MfaMethodEnum';
|
|
2
|
+
/**
|
|
3
|
+
* Body del POST /auth/resend-otp (público, anónimo). DEC-RBAC-054.
|
|
4
|
+
* Reenvía el OTP del login re-disparando el challenge real CUSTOM_AUTH (EMAIL_OTP) para la
|
|
5
|
+
* identidad SIN password. `tenantId` obligatorio (DEC-064 — el picker ya lo resolvió, NO "solo email").
|
|
6
|
+
* El email se normaliza lowercase server-side. Postura anti-enumeración: respuesta 200 genérica
|
|
7
|
+
* siempre, sin filtrar existencia (ver AuthLoginManager.resendChallengeOtp).
|
|
8
|
+
*/
|
|
9
|
+
export declare class ResendOtpRequest {
|
|
10
|
+
email: string;
|
|
11
|
+
tenantId: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Respuesta del resend-otp. `session`/`mfaMethod` frescos del nuevo challenge CUSTOM_AUTH.
|
|
15
|
+
* Plain sin validators (no validamos lo que mandamos al cliente — fiado-validation-and-dtos § 7).
|
|
16
|
+
* Ambos opcionales: en los caminos de rechazo silencioso (anti-enumeración) o ramas sin CUSTOM_AUTH
|
|
17
|
+
* el server responde 200 genérico sin session ni método.
|
|
18
|
+
*/
|
|
19
|
+
export interface ResendOtpResponse {
|
|
20
|
+
session?: string;
|
|
21
|
+
mfaMethod?: MfaMethodEnum;
|
|
22
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ResendOtpRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* Body del POST /auth/resend-otp (público, anónimo). DEC-RBAC-054.
|
|
17
|
+
* Reenvía el OTP del login re-disparando el challenge real CUSTOM_AUTH (EMAIL_OTP) para la
|
|
18
|
+
* identidad SIN password. `tenantId` obligatorio (DEC-064 — el picker ya lo resolvió, NO "solo email").
|
|
19
|
+
* El email se normaliza lowercase server-side. Postura anti-enumeración: respuesta 200 genérica
|
|
20
|
+
* siempre, sin filtrar existencia (ver AuthLoginManager.resendChallengeOtp).
|
|
21
|
+
*/
|
|
22
|
+
class ResendOtpRequest {
|
|
23
|
+
}
|
|
24
|
+
exports.ResendOtpRequest = ResendOtpRequest;
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_transformer_1.Expose)(),
|
|
27
|
+
(0, class_validator_1.IsEmail)(),
|
|
28
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], ResendOtpRequest.prototype, "email", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_transformer_1.Expose)(),
|
|
33
|
+
(0, class_validator_1.IsString)(),
|
|
34
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], ResendOtpRequest.prototype, "tenantId", void 0);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body del POST /self-register/resend-otp (público, anónimo). DEC-RBAC-054.
|
|
3
|
+
* Re-envía el OTP del autoregistro (mecanismo messages-business, NO Cognito) tras validar un
|
|
4
|
+
* `pending` existente. Misma postura anti-enumeración del start. El email se normaliza lowercase
|
|
5
|
+
* server-side. DTO propio por endpoint (NO reusa SelfRegisterStartRequest, que exige roleId/scope/
|
|
6
|
+
* scopeRef, ni SelfRegisterVerifyOtpRequest, que exige otp).
|
|
7
|
+
*/
|
|
8
|
+
export declare class ResendSelfRegisterOtpRequest {
|
|
9
|
+
tenantId: string;
|
|
10
|
+
email: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ResendSelfRegisterOtpRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* Body del POST /self-register/resend-otp (público, anónimo). DEC-RBAC-054.
|
|
17
|
+
* Re-envía el OTP del autoregistro (mecanismo messages-business, NO Cognito) tras validar un
|
|
18
|
+
* `pending` existente. Misma postura anti-enumeración del start. El email se normaliza lowercase
|
|
19
|
+
* server-side. DTO propio por endpoint (NO reusa SelfRegisterStartRequest, que exige roleId/scope/
|
|
20
|
+
* scopeRef, ni SelfRegisterVerifyOtpRequest, que exige otp).
|
|
21
|
+
*/
|
|
22
|
+
class ResendSelfRegisterOtpRequest {
|
|
23
|
+
}
|
|
24
|
+
exports.ResendSelfRegisterOtpRequest = ResendSelfRegisterOtpRequest;
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_transformer_1.Expose)(),
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], ResendSelfRegisterOtpRequest.prototype, "tenantId", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_transformer_1.Expose)(),
|
|
33
|
+
(0, class_validator_1.IsEmail)(),
|
|
34
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], ResendSelfRegisterOtpRequest.prototype, "email", void 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body del PUT /platform/tenants/{tenantId}/integrations/{integrationId}.
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ **Semántica de MERGE, no de reemplazo**: solo se actualiza lo que venga. Un campo ausente se
|
|
5
|
+
* deja como está, NO se borra.
|
|
6
|
+
*
|
|
7
|
+
* Es PUT y no PATCH porque `PATCH` no existe en este stack — el enum `HttpMethod` del
|
|
8
|
+
* `@fiado/gateway-adapter` tiene GET/POST/PUT/DELETE, y el CORS y los `GatewayResponses` tampoco lo
|
|
9
|
+
* listan. Mismo precedente que `backofficeUpdateTenantUserField`.
|
|
10
|
+
*
|
|
11
|
+
* El merge no es cosmético: con reemplazo total, un body que omitiera `ipAllowlist` la borraría, y
|
|
12
|
+
* eso apagaría el filtro por IP de la integración sin que nadie lo pidiera.
|
|
13
|
+
*/
|
|
14
|
+
export declare class UpdateIntegrationRequest {
|
|
15
|
+
displayName?: string;
|
|
16
|
+
ipAllowlist?: string[];
|
|
17
|
+
updatedBy: string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.UpdateIntegrationRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* Body del PUT /platform/tenants/{tenantId}/integrations/{integrationId}.
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ **Semántica de MERGE, no de reemplazo**: solo se actualiza lo que venga. Un campo ausente se
|
|
19
|
+
* deja como está, NO se borra.
|
|
20
|
+
*
|
|
21
|
+
* Es PUT y no PATCH porque `PATCH` no existe en este stack — el enum `HttpMethod` del
|
|
22
|
+
* `@fiado/gateway-adapter` tiene GET/POST/PUT/DELETE, y el CORS y los `GatewayResponses` tampoco lo
|
|
23
|
+
* listan. Mismo precedente que `backofficeUpdateTenantUserField`.
|
|
24
|
+
*
|
|
25
|
+
* El merge no es cosmético: con reemplazo total, un body que omitiera `ipAllowlist` la borraría, y
|
|
26
|
+
* eso apagaría el filtro por IP de la integración sin que nadie lo pidiera.
|
|
27
|
+
*/
|
|
28
|
+
class UpdateIntegrationRequest {
|
|
29
|
+
}
|
|
30
|
+
exports.UpdateIntegrationRequest = UpdateIntegrationRequest;
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_transformer_1.Expose)(),
|
|
33
|
+
(0, class_validator_1.IsOptional)(),
|
|
34
|
+
(0, class_validator_1.IsString)(),
|
|
35
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
36
|
+
__metadata("design:type", String)
|
|
37
|
+
], UpdateIntegrationRequest.prototype, "displayName", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
(0, class_transformer_1.Expose)(),
|
|
40
|
+
(0, class_validator_1.IsOptional)(),
|
|
41
|
+
(0, class_validator_1.IsArray)(),
|
|
42
|
+
(0, class_validator_1.ArrayNotEmpty)(),
|
|
43
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
44
|
+
__metadata("design:type", Array)
|
|
45
|
+
], UpdateIntegrationRequest.prototype, "ipAllowlist", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
(0, class_transformer_1.Expose)(),
|
|
48
|
+
(0, class_validator_1.IsString)(),
|
|
49
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], UpdateIntegrationRequest.prototype, "updatedBy", void 0);
|
|
@@ -114,7 +114,12 @@ export declare enum Permission {
|
|
|
114
114
|
LEVEL3_ROLE_DELETE = "level3.role.delete",
|
|
115
115
|
LEVEL3_ROLE_ASSIGN = "level3.role.assign",
|
|
116
116
|
LEVEL3_ROLE_REVOKE = "level3.role.revoke",
|
|
117
|
-
LEVEL3_AUDIT_VIEW = "level3.audit.view"
|
|
117
|
+
LEVEL3_AUDIT_VIEW = "level3.audit.view",
|
|
118
|
+
PLATFORM_INTEGRATION_VIEW = "platform.integration.view",
|
|
119
|
+
PLATFORM_INTEGRATION_MANAGE = "platform.integration.manage",
|
|
120
|
+
PLATFORM_INTEGRATION_KEY_ISSUE = "platform.integration.key.issue",
|
|
121
|
+
PLATFORM_INTEGRATION_KEY_REVOKE = "platform.integration.key.revoke",
|
|
122
|
+
TENANT_INTEGRATION_DIAGNOSTIC = "tenant.integration.diagnostic"
|
|
118
123
|
}
|
|
119
124
|
/**
|
|
120
125
|
* Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
|
|
@@ -149,6 +149,21 @@ var Permission;
|
|
|
149
149
|
Permission["LEVEL3_ROLE_ASSIGN"] = "level3.role.assign";
|
|
150
150
|
Permission["LEVEL3_ROLE_REVOKE"] = "level3.role.revoke";
|
|
151
151
|
Permission["LEVEL3_AUDIT_VIEW"] = "level3.audit.view";
|
|
152
|
+
// Append-only 2026-08-10 (DEC-RBAC-120/121/126): integraciones M2M con socios externos.
|
|
153
|
+
// Los cuatro de ADMINISTRACIÓN son scope PLATFORM: los datos de la integración son del tenant,
|
|
154
|
+
// pero solo un usuario de plataforma la crea, rota o revoca. Son además el set exacto que la
|
|
155
|
+
// guarda 1 prohíbe asignarle a un principal `INT#` — una integración jamás puede administrarse
|
|
156
|
+
// a sí misma.
|
|
157
|
+
Permission["PLATFORM_INTEGRATION_VIEW"] = "platform.integration.view";
|
|
158
|
+
Permission["PLATFORM_INTEGRATION_MANAGE"] = "platform.integration.manage";
|
|
159
|
+
Permission["PLATFORM_INTEGRATION_KEY_ISSUE"] = "platform.integration.key.issue";
|
|
160
|
+
Permission["PLATFORM_INTEGRATION_KEY_REVOKE"] = "platform.integration.key.revoke";
|
|
161
|
+
// DEC-RBAC-126: el endpoint de diagnóstico del authorizer W5 lo llama la INTEGRACIÓN, no un
|
|
162
|
+
// humano — y una integración NUNCA puede portar permisos de scope PLATFORM (computeRoleScope
|
|
163
|
+
// toma el MAX de los scopes del rol, así que uno solo lo volvería PLATFORM con scopeRef '*').
|
|
164
|
+
// Por eso este es TENANT-scoped. Y por eso NO entra en el set de la guarda 1: no administra
|
|
165
|
+
// nada, solo devuelve quién sos.
|
|
166
|
+
Permission["TENANT_INTEGRATION_DIAGNOSTIC"] = "tenant.integration.diagnostic";
|
|
152
167
|
})(Permission || (exports.Permission = Permission = {}));
|
|
153
168
|
/**
|
|
154
169
|
* Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
|
|
@@ -261,6 +276,13 @@ exports.PERMISSION_BIT_ORDER = [
|
|
|
261
276
|
Permission.LEVEL3_ROLE_ASSIGN,
|
|
262
277
|
Permission.LEVEL3_ROLE_REVOKE,
|
|
263
278
|
Permission.LEVEL3_AUDIT_VIEW,
|
|
279
|
+
// Append-only 2026-08-10 (DEC-RBAC-120/126): integraciones M2M. Van AL FINAL y en este orden,
|
|
280
|
+
// nunca intercalados: reordenar desalinearía los bits de los tokens ya emitidos.
|
|
281
|
+
Permission.PLATFORM_INTEGRATION_VIEW,
|
|
282
|
+
Permission.PLATFORM_INTEGRATION_MANAGE,
|
|
283
|
+
Permission.PLATFORM_INTEGRATION_KEY_ISSUE,
|
|
284
|
+
Permission.PLATFORM_INTEGRATION_KEY_REVOKE,
|
|
285
|
+
Permission.TENANT_INTEGRATION_DIAGNOSTIC,
|
|
264
286
|
];
|
|
265
287
|
function djb2(input) {
|
|
266
288
|
let h = 5381;
|
|
@@ -55,3 +55,8 @@ export * from './dtos/CreateLevelEntityRequest';
|
|
|
55
55
|
export type { CreateLevelEntityResponse } from './dtos/CreateLevelEntityResponse';
|
|
56
56
|
export * from './dtos/CreateTenantUserRequest';
|
|
57
57
|
export type { CreateTenantUserResponse } from './dtos/CreateTenantUserResponse';
|
|
58
|
+
export * from './dtos/CreateIntegrationRequest';
|
|
59
|
+
export * from './dtos/UpdateIntegrationRequest';
|
|
60
|
+
export type { IntegrationResponse, IntegrationStatusValue } from './dtos/IntegrationResponse';
|
|
61
|
+
export type { IntegrationKeyResponse, IntegrationKeyStatusValue, IssueIntegrationKeyResponse, } from './dtos/IntegrationKeyResponse';
|
|
62
|
+
export type { IntegrationWhoamiResponse } from './dtos/IntegrationWhoamiResponse';
|
|
@@ -111,3 +111,7 @@ __exportStar(require("./dtos/SelfRegisterCompleteRequest"), exports);
|
|
|
111
111
|
// Response son interfaces plain → type-only. Consumidos por retail-org vía api-invoker (Publisher).
|
|
112
112
|
__exportStar(require("./dtos/CreateLevelEntityRequest"), exports);
|
|
113
113
|
__exportStar(require("./dtos/CreateTenantUserRequest"), exports);
|
|
114
|
+
// DEC-RBAC-120/121/126: integraciones M2M con socios externos (API keys como principal del RBAC).
|
|
115
|
+
// Los requests van como clase (class-validator); las responses como tipo.
|
|
116
|
+
__exportStar(require("./dtos/CreateIntegrationRequest"), exports);
|
|
117
|
+
__exportStar(require("./dtos/UpdateIntegrationRequest"), exports);
|
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { ArrayNotEmpty, IsArray, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Body del POST /platform/tenants/{tenantId}/integrations. `tenantId` viaja en el path.
|
|
6
|
+
*
|
|
7
|
+
* Da de alta una integración M2M con un socio externo (DEC-RBAC-120/121). Los datos son del tenant
|
|
8
|
+
* pero **solo un usuario de plataforma** puede crearla.
|
|
9
|
+
*
|
|
10
|
+
* `roleId` es un rol del silo del tenant, elegido de los que ya existen — no se siembra uno
|
|
11
|
+
* especial. Está sujeto a las guardas anti-escalada: no puede contener permisos de administración
|
|
12
|
+
* de integraciones ni calcular scope PLATFORM (DEC-RBAC-122/126).
|
|
13
|
+
*
|
|
14
|
+
* `ipAllowlist` es OPCIONAL y su semántica es permisiva (spec §5): ausente, vacía o `['*']` ⇒ sin
|
|
15
|
+
* restricción de IP. Que se pueda apagar es deliberado; que se apague en silencio, no — por eso la
|
|
16
|
+
* pantalla marca las integraciones sin restricción.
|
|
17
|
+
*/
|
|
18
|
+
export class CreateIntegrationRequest {
|
|
19
|
+
@Expose() @IsString() @IsNotEmpty() displayName!: string;
|
|
20
|
+
@Expose() @IsString() @IsNotEmpty() roleId!: string;
|
|
21
|
+
@Expose() @IsOptional() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) ipAllowlist?: string[];
|
|
22
|
+
/** cognitoSub del operador real (audit + grantedBy del assignment). */
|
|
23
|
+
@Expose() @IsString() @IsNotEmpty() createdBy!: string;
|
|
24
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estado de una llave. NO existe `ROTATING`: rotar es emitir una segunda llave y revocar la vieja,
|
|
3
|
+
* con las dos activas mientras dura la migración del socio.
|
|
4
|
+
*/
|
|
5
|
+
export type IntegrationKeyStatusValue = 'ACTIVE' | 'REVOKED';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Una llave, tal como la devuelve el listado.
|
|
9
|
+
*
|
|
10
|
+
* 🔴 **NUNCA lleva el secreto ni el `secretHash`.** El secreto en claro se devuelve exactamente una
|
|
11
|
+
* vez, en la respuesta del POST que lo emite (`IssueIntegrationKeyResponse`), y no existe ningún
|
|
12
|
+
* endpoint que lo lea de vuelta.
|
|
13
|
+
*
|
|
14
|
+
* `lastUsedAt` y `lastUsedIp` los escribe el authorizer W5, con throttle: sirven para detectar una
|
|
15
|
+
* integración que dejó de llamar, que es uno de los dos incidentes clásicos de un canal M2M.
|
|
16
|
+
*/
|
|
17
|
+
export interface IntegrationKeyResponse {
|
|
18
|
+
keyId: string;
|
|
19
|
+
integrationId: string;
|
|
20
|
+
status: IntegrationKeyStatusValue;
|
|
21
|
+
/** epoch ms. Ausente = no vence. */
|
|
22
|
+
expiresAt?: number;
|
|
23
|
+
lastUsedAt?: number;
|
|
24
|
+
lastUsedIp?: string;
|
|
25
|
+
createdAt: number;
|
|
26
|
+
createdBy?: string;
|
|
27
|
+
revokedAt?: number;
|
|
28
|
+
revokedBy?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Respuesta del POST que emite una llave. **El único lugar de todo el sistema donde el secreto
|
|
33
|
+
* viaja en claro.**
|
|
34
|
+
*
|
|
35
|
+
* Quien lo consuma tiene que mostrarlo una sola vez y no persistirlo: no hay forma de recuperarlo
|
|
36
|
+
* después, porque en base solo queda su hash. Si se pierde, se emite otra llave.
|
|
37
|
+
*/
|
|
38
|
+
export interface IssueIntegrationKeyResponse extends IntegrationKeyResponse {
|
|
39
|
+
/** `fdo_sk.<keyId>.<secreto>` — se muestra UNA vez y no se vuelve a poder leer. */
|
|
40
|
+
token: string;
|
|
41
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Estado de una integración. Suspender corta TODAS sus llaves de una. */
|
|
2
|
+
export type IntegrationStatusValue = 'ACTIVE' | 'SUSPENDED';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Una integración, tal como la devuelven el GET de detalle y el listado.
|
|
6
|
+
*
|
|
7
|
+
* NO lleva nada del secreto de sus llaves — ni el valor ni el hash. Para eso está
|
|
8
|
+
* `IntegrationKeyResponse`, que tampoco los lleva.
|
|
9
|
+
*/
|
|
10
|
+
export interface IntegrationResponse {
|
|
11
|
+
integrationId: string;
|
|
12
|
+
tenantId: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
status: IntegrationStatusValue;
|
|
15
|
+
/** Rol del silo que porta esta integración. */
|
|
16
|
+
roleId: string;
|
|
17
|
+
/**
|
|
18
|
+
* CIDRs permitidos. Vacío o `['*']` ⇒ **sin restricción de IP** (spec §5).
|
|
19
|
+
* El front lo marca visiblemente en la lista: la protección se puede apagar, pero no en silencio.
|
|
20
|
+
*/
|
|
21
|
+
ipAllowlist: string[];
|
|
22
|
+
createdAt: number;
|
|
23
|
+
updatedAt: number;
|
|
24
|
+
createdBy?: string;
|
|
25
|
+
updatedBy?: string;
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Respuesta del endpoint de diagnóstico del authorizer W5.
|
|
3
|
+
*
|
|
4
|
+
* Devuelve **el principal ya resuelto**, no un "ok". Eso es lo que lo hace útil como prueba de la
|
|
5
|
+
* cadena completa: no verifica que el request pase, sino que haya resuelto como quien debía —
|
|
6
|
+
* con el tenant correcto y con los permisos que su rol otorga.
|
|
7
|
+
*
|
|
8
|
+
* 🔴 Endpoint TEMPORAL, solo dev: expone la lista de permisos del principal. Se saca antes de
|
|
9
|
+
* producción (el permiso `tenant.integration.diagnostic` en cambio se queda, marcado deprecado:
|
|
10
|
+
* quitarlo del enum rompería la cobertura bidireccional del catálogo y dejaría
|
|
11
|
+
* `UnknownPermissionError` en cualquier rol ya sembrado con él).
|
|
12
|
+
*/
|
|
13
|
+
export interface IntegrationWhoamiResponse {
|
|
14
|
+
principalType: 'INTEGRATION';
|
|
15
|
+
/** Con prefijo `INT#`. */
|
|
16
|
+
principalId: string;
|
|
17
|
+
integrationId: string;
|
|
18
|
+
tenantId: string;
|
|
19
|
+
/** Los permisos que resolvió el RBAC para este principal — el punto de la prueba. */
|
|
20
|
+
permissions: string[];
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { ArrayNotEmpty, IsArray, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Body del PUT /platform/tenants/{tenantId}/integrations/{integrationId}.
|
|
6
|
+
*
|
|
7
|
+
* ⚠️ **Semántica de MERGE, no de reemplazo**: solo se actualiza lo que venga. Un campo ausente se
|
|
8
|
+
* deja como está, NO se borra.
|
|
9
|
+
*
|
|
10
|
+
* Es PUT y no PATCH porque `PATCH` no existe en este stack — el enum `HttpMethod` del
|
|
11
|
+
* `@fiado/gateway-adapter` tiene GET/POST/PUT/DELETE, y el CORS y los `GatewayResponses` tampoco lo
|
|
12
|
+
* listan. Mismo precedente que `backofficeUpdateTenantUserField`.
|
|
13
|
+
*
|
|
14
|
+
* El merge no es cosmético: con reemplazo total, un body que omitiera `ipAllowlist` la borraría, y
|
|
15
|
+
* eso apagaría el filtro por IP de la integración sin que nadie lo pidiera.
|
|
16
|
+
*/
|
|
17
|
+
export class UpdateIntegrationRequest {
|
|
18
|
+
@Expose() @IsOptional() @IsString() @IsNotEmpty() displayName?: string;
|
|
19
|
+
@Expose() @IsOptional() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) ipAllowlist?: string[];
|
|
20
|
+
@Expose() @IsString() @IsNotEmpty() updatedBy!: string;
|
|
21
|
+
}
|
|
@@ -146,6 +146,23 @@ export enum Permission {
|
|
|
146
146
|
LEVEL3_ROLE_ASSIGN = 'level3.role.assign',
|
|
147
147
|
LEVEL3_ROLE_REVOKE = 'level3.role.revoke',
|
|
148
148
|
LEVEL3_AUDIT_VIEW = 'level3.audit.view',
|
|
149
|
+
|
|
150
|
+
// Append-only 2026-08-10 (DEC-RBAC-120/121/126): integraciones M2M con socios externos.
|
|
151
|
+
// Los cuatro de ADMINISTRACIÓN son scope PLATFORM: los datos de la integración son del tenant,
|
|
152
|
+
// pero solo un usuario de plataforma la crea, rota o revoca. Son además el set exacto que la
|
|
153
|
+
// guarda 1 prohíbe asignarle a un principal `INT#` — una integración jamás puede administrarse
|
|
154
|
+
// a sí misma.
|
|
155
|
+
PLATFORM_INTEGRATION_VIEW = 'platform.integration.view',
|
|
156
|
+
PLATFORM_INTEGRATION_MANAGE = 'platform.integration.manage',
|
|
157
|
+
PLATFORM_INTEGRATION_KEY_ISSUE = 'platform.integration.key.issue',
|
|
158
|
+
PLATFORM_INTEGRATION_KEY_REVOKE = 'platform.integration.key.revoke',
|
|
159
|
+
|
|
160
|
+
// DEC-RBAC-126: el endpoint de diagnóstico del authorizer W5 lo llama la INTEGRACIÓN, no un
|
|
161
|
+
// humano — y una integración NUNCA puede portar permisos de scope PLATFORM (computeRoleScope
|
|
162
|
+
// toma el MAX de los scopes del rol, así que uno solo lo volvería PLATFORM con scopeRef '*').
|
|
163
|
+
// Por eso este es TENANT-scoped. Y por eso NO entra en el set de la guarda 1: no administra
|
|
164
|
+
// nada, solo devuelve quién sos.
|
|
165
|
+
TENANT_INTEGRATION_DIAGNOSTIC = 'tenant.integration.diagnostic',
|
|
149
166
|
}
|
|
150
167
|
|
|
151
168
|
/**
|
|
@@ -259,6 +276,13 @@ export const PERMISSION_BIT_ORDER: readonly Permission[] = [
|
|
|
259
276
|
Permission.LEVEL3_ROLE_ASSIGN,
|
|
260
277
|
Permission.LEVEL3_ROLE_REVOKE,
|
|
261
278
|
Permission.LEVEL3_AUDIT_VIEW,
|
|
279
|
+
// Append-only 2026-08-10 (DEC-RBAC-120/126): integraciones M2M. Van AL FINAL y en este orden,
|
|
280
|
+
// nunca intercalados: reordenar desalinearía los bits de los tokens ya emitidos.
|
|
281
|
+
Permission.PLATFORM_INTEGRATION_VIEW,
|
|
282
|
+
Permission.PLATFORM_INTEGRATION_MANAGE,
|
|
283
|
+
Permission.PLATFORM_INTEGRATION_KEY_ISSUE,
|
|
284
|
+
Permission.PLATFORM_INTEGRATION_KEY_REVOKE,
|
|
285
|
+
Permission.TENANT_INTEGRATION_DIAGNOSTIC,
|
|
262
286
|
] as const;
|
|
263
287
|
|
|
264
288
|
function djb2(input: string): number {
|
|
@@ -138,3 +138,15 @@ export * from './dtos/CreateLevelEntityRequest';
|
|
|
138
138
|
export type { CreateLevelEntityResponse } from './dtos/CreateLevelEntityResponse';
|
|
139
139
|
export * from './dtos/CreateTenantUserRequest';
|
|
140
140
|
export type { CreateTenantUserResponse } from './dtos/CreateTenantUserResponse';
|
|
141
|
+
|
|
142
|
+
// DEC-RBAC-120/121/126: integraciones M2M con socios externos (API keys como principal del RBAC).
|
|
143
|
+
// Los requests van como clase (class-validator); las responses como tipo.
|
|
144
|
+
export * from './dtos/CreateIntegrationRequest';
|
|
145
|
+
export * from './dtos/UpdateIntegrationRequest';
|
|
146
|
+
export type { IntegrationResponse, IntegrationStatusValue } from './dtos/IntegrationResponse';
|
|
147
|
+
export type {
|
|
148
|
+
IntegrationKeyResponse,
|
|
149
|
+
IntegrationKeyStatusValue,
|
|
150
|
+
IssueIntegrationKeyResponse,
|
|
151
|
+
} from './dtos/IntegrationKeyResponse';
|
|
152
|
+
export type { IntegrationWhoamiResponse } from './dtos/IntegrationWhoamiResponse';
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Body de PUT /credits/:creditId/checklist (loan-credit-business). Marca condiciones de activación
|
|
3
|
-
* cumplidas. Solo se mandan las que cambian; en F3 las marcarán los flujos de firma de contrato
|
|
4
|
-
* (`downPayment` + `contractSigned`) y de enrolamiento MDM (`imeiEnrolled` + `lockVerified`).
|
|
5
|
-
*/
|
|
6
|
-
export declare class UpdateActivationChecklistRequest {
|
|
7
|
-
downPayment?: boolean;
|
|
8
|
-
contractSigned?: boolean;
|
|
9
|
-
imeiEnrolled?: boolean;
|
|
10
|
-
lockVerified?: boolean;
|
|
11
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.UpdateActivationChecklistRequest = void 0;
|
|
13
|
-
const class_transformer_1 = require("class-transformer");
|
|
14
|
-
const class_validator_1 = require("class-validator");
|
|
15
|
-
/**
|
|
16
|
-
* Body de PUT /credits/:creditId/checklist (loan-credit-business). Marca condiciones de activación
|
|
17
|
-
* cumplidas. Solo se mandan las que cambian; en F3 las marcarán los flujos de firma de contrato
|
|
18
|
-
* (`downPayment` + `contractSigned`) y de enrolamiento MDM (`imeiEnrolled` + `lockVerified`).
|
|
19
|
-
*/
|
|
20
|
-
class UpdateActivationChecklistRequest {
|
|
21
|
-
}
|
|
22
|
-
exports.UpdateActivationChecklistRequest = UpdateActivationChecklistRequest;
|
|
23
|
-
__decorate([
|
|
24
|
-
(0, class_transformer_1.Expose)(),
|
|
25
|
-
(0, class_validator_1.IsOptional)(),
|
|
26
|
-
(0, class_validator_1.IsBoolean)(),
|
|
27
|
-
__metadata("design:type", Boolean)
|
|
28
|
-
], UpdateActivationChecklistRequest.prototype, "downPayment", void 0);
|
|
29
|
-
__decorate([
|
|
30
|
-
(0, class_transformer_1.Expose)(),
|
|
31
|
-
(0, class_validator_1.IsOptional)(),
|
|
32
|
-
(0, class_validator_1.IsBoolean)(),
|
|
33
|
-
__metadata("design:type", Boolean)
|
|
34
|
-
], UpdateActivationChecklistRequest.prototype, "contractSigned", void 0);
|
|
35
|
-
__decorate([
|
|
36
|
-
(0, class_transformer_1.Expose)(),
|
|
37
|
-
(0, class_validator_1.IsOptional)(),
|
|
38
|
-
(0, class_validator_1.IsBoolean)(),
|
|
39
|
-
__metadata("design:type", Boolean)
|
|
40
|
-
], UpdateActivationChecklistRequest.prototype, "imeiEnrolled", void 0);
|
|
41
|
-
__decorate([
|
|
42
|
-
(0, class_transformer_1.Expose)(),
|
|
43
|
-
(0, class_validator_1.IsOptional)(),
|
|
44
|
-
(0, class_validator_1.IsBoolean)(),
|
|
45
|
-
__metadata("design:type", Boolean)
|
|
46
|
-
], UpdateActivationChecklistRequest.prototype, "lockVerified", void 0);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nivel del cliente según su SCI (M7/05_MOTOR §3.2): 21-60 Bronce · 61-80 Plata · 81-100 Oro.
|
|
3
|
-
* Distinto de `CreditPlanLevelEnum` de loanOfferings (que además tiene `ALL` para planes):
|
|
4
|
-
* un CLIENTE nunca es `ALL`.
|
|
5
|
-
* @enum {string}
|
|
6
|
-
*/
|
|
7
|
-
export declare enum ClientLevelEnum {
|
|
8
|
-
BRONZE = "BRONZE",
|
|
9
|
-
SILVER = "SILVER",
|
|
10
|
-
GOLD = "GOLD"
|
|
11
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ClientLevelEnum = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Nivel del cliente según su SCI (M7/05_MOTOR §3.2): 21-60 Bronce · 61-80 Plata · 81-100 Oro.
|
|
6
|
-
* Distinto de `CreditPlanLevelEnum` de loanOfferings (que además tiene `ALL` para planes):
|
|
7
|
-
* un CLIENTE nunca es `ALL`.
|
|
8
|
-
* @enum {string}
|
|
9
|
-
*/
|
|
10
|
-
var ClientLevelEnum;
|
|
11
|
-
(function (ClientLevelEnum) {
|
|
12
|
-
ClientLevelEnum["BRONZE"] = "BRONZE";
|
|
13
|
-
ClientLevelEnum["SILVER"] = "SILVER";
|
|
14
|
-
ClientLevelEnum["GOLD"] = "GOLD";
|
|
15
|
-
})(ClientLevelEnum || (exports.ClientLevelEnum = ClientLevelEnum = {}));
|