@fiado/type-kit 3.69.0 → 3.71.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/cognitoBackofficeConnector/dtos/CreateUserRequest.test.ts +13 -0
- package/_test_/unit/platformRbac/dtos/effectivePermissions.test.ts +22 -0
- package/_test_/unit/platformRbac/enums/__snapshots__/permissionBits.test.ts.snap +98 -0
- package/_test_/unit/platformRbac/enums/permissionBits.test.ts +36 -0
- package/bin/cognitoBackofficeConnector/dtos/CreateUserRequest.d.ts +2 -2
- package/bin/cognitoBackofficeConnector/dtos/CreateUserRequest.js +2 -2
- package/bin/index.d.ts +1 -0
- package/bin/index.js +2 -1
- package/bin/milestone-business/dtos/Milestone.d.ts +24 -0
- package/bin/milestone-business/dtos/Milestone.js +2 -0
- package/bin/milestone-business/dtos/MilestonesByDirectoryIdsRequest.d.ts +19 -0
- package/bin/milestone-business/dtos/MilestonesByDirectoryIdsRequest.js +39 -0
- package/bin/milestone-business/dtos/MilestonesByDirectoryIdsResponse.d.ts +10 -0
- package/bin/milestone-business/dtos/MilestonesByDirectoryIdsResponse.js +2 -0
- package/bin/milestone-business/index.d.ts +3 -0
- package/bin/milestone-business/index.js +4 -0
- package/bin/platformRbac/dtos/AuthContext.d.ts +6 -0
- package/bin/platformRbac/dtos/EffectivePermissionsResponse.d.ts +8 -0
- package/bin/platformRbac/dtos/EffectivePermissionsResponse.js +2 -0
- package/bin/platformRbac/enums/Permission.d.ts +13 -0
- package/bin/platformRbac/enums/Permission.js +140 -1
- package/bin/platformRbac/index.d.ts +2 -1
- package/bin/platformRbac/index.js +8 -4
- package/bin/twilioConnector/dtos/ConnectorSendMessageRequest.d.ts +27 -0
- package/bin/twilioConnector/dtos/ConnectorSendMessageRequest.js +62 -0
- package/bin/twilioConnector/dtos/ConnectorSendMessageResponse.d.ts +9 -0
- package/bin/twilioConnector/dtos/ConnectorSendMessageResponse.js +30 -0
- package/bin/twilioConnector/dtos/SelectedProvider.d.ts +21 -0
- package/bin/twilioConnector/dtos/SelectedProvider.js +47 -0
- package/bin/twilioConnector/index.d.ts +3 -0
- package/bin/twilioConnector/index.js +19 -0
- package/package.json +1 -1
- package/src/cognitoBackofficeConnector/dtos/CreateUserRequest.ts +5 -2
- package/src/index.ts +1 -0
- package/src/milestone-business/dtos/Milestone.ts +24 -0
- package/src/milestone-business/dtos/MilestonesByDirectoryIdsRequest.ts +26 -0
- package/src/milestone-business/dtos/MilestonesByDirectoryIdsResponse.ts +11 -0
- package/src/milestone-business/index.ts +6 -0
- package/src/platformRbac/dtos/AuthContext.ts +6 -0
- package/src/platformRbac/dtos/EffectivePermissionsResponse.ts +9 -0
- package/src/platformRbac/enums/Permission.ts +136 -0
- package/src/platformRbac/index.ts +11 -4
- package/src/twilioConnector/dtos/ConnectorSendMessageRequest.ts +34 -0
- package/src/twilioConnector/dtos/ConnectorSendMessageResponse.ts +13 -0
- package/src/twilioConnector/dtos/SelectedProvider.ts +27 -0
- package/src/twilioConnector/index.ts +3 -0
|
@@ -38,6 +38,19 @@ describe('CreateUserRequest', () => {
|
|
|
38
38
|
expect(errors.some(e => e.property === 'tenantId')).toBe(true);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
+
// userPoolId + region pasan a ser OPCIONALES: el front del alta de usuario PLATFORM deja de
|
|
42
|
+
// mandarlos y el backend (platform-rbac-business) los resuelve de la config del tenant 'platform'.
|
|
43
|
+
// Quedan en el DTO por compatibilidad con los demás callers del connector que SÍ los proveen.
|
|
44
|
+
it('valida sin userPoolId ni region (alta platform — el backend los resuelve)', async () => {
|
|
45
|
+
const dto = plainToInstance(CreateUserRequest, {
|
|
46
|
+
email: 'user@acme.com',
|
|
47
|
+
tenantId: 'platform',
|
|
48
|
+
});
|
|
49
|
+
const errors = await validate(dto);
|
|
50
|
+
expect(errors.some(e => e.property === 'userPoolId')).toBe(false);
|
|
51
|
+
expect(errors.some(e => e.property === 'region')).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
|
|
41
54
|
it('preserva los campos opcionales legítimos', async () => {
|
|
42
55
|
const dto = plainToInstance(CreateUserRequest, {
|
|
43
56
|
...valid,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import type { AuthContext, EffectivePermissionsResponse } from '../../../../src/platformRbac/index';
|
|
3
|
+
|
|
4
|
+
it('AuthContext acepta los campos opcionales del token-as-cache', () => {
|
|
5
|
+
const ctx: AuthContext = {
|
|
6
|
+
cognitoSub: 's',
|
|
7
|
+
tenantId: 't',
|
|
8
|
+
email: 'e',
|
|
9
|
+
roleAssignments: [],
|
|
10
|
+
permissions: [],
|
|
11
|
+
resolvedAt: 'now',
|
|
12
|
+
permBits: 'AAA',
|
|
13
|
+
permVer: 1,
|
|
14
|
+
permsEpoch: 3,
|
|
15
|
+
};
|
|
16
|
+
expect(ctx.permVer).toBe(1);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('EffectivePermissionsResponse tiene permissions + roleAssignments + epoch', () => {
|
|
20
|
+
const r: EffectivePermissionsResponse = { permissions: [], roleAssignments: [], permsEpoch: 0 };
|
|
21
|
+
expect(r.permsEpoch).toBe(0);
|
|
22
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
|
2
|
+
|
|
3
|
+
exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `4037934643`;
|
|
4
|
+
|
|
5
|
+
exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe ante cualquier reorden/inserción) 1`] = `
|
|
6
|
+
[
|
|
7
|
+
"rbac.catalog.manage",
|
|
8
|
+
"platform.tenant.create",
|
|
9
|
+
"platform.tenant.list",
|
|
10
|
+
"platform.tenant.view",
|
|
11
|
+
"platform.tenant.update",
|
|
12
|
+
"platform.tenant.suspend",
|
|
13
|
+
"platform.tenant.activate",
|
|
14
|
+
"platform.tenant.admin.replace",
|
|
15
|
+
"platform.cognito.pool.manage",
|
|
16
|
+
"platform.cognito.pool.list",
|
|
17
|
+
"platform.user.create",
|
|
18
|
+
"platform.user.list",
|
|
19
|
+
"platform.user.view",
|
|
20
|
+
"platform.user.update",
|
|
21
|
+
"platform.user.disable",
|
|
22
|
+
"platform.user.enable",
|
|
23
|
+
"platform.user.delete",
|
|
24
|
+
"platform.role.create",
|
|
25
|
+
"platform.role.list",
|
|
26
|
+
"platform.role.update",
|
|
27
|
+
"platform.role.delete",
|
|
28
|
+
"platform.audit.view",
|
|
29
|
+
"tenant.user.create",
|
|
30
|
+
"tenant.user.create.lateral",
|
|
31
|
+
"tenant.user.read",
|
|
32
|
+
"tenant.user.status",
|
|
33
|
+
"tenant.user.list",
|
|
34
|
+
"tenant.user.view",
|
|
35
|
+
"tenant.user.update",
|
|
36
|
+
"tenant.user.disable",
|
|
37
|
+
"tenant.user.enable",
|
|
38
|
+
"tenant.user.delete",
|
|
39
|
+
"tenant.user.mfa.reset",
|
|
40
|
+
"tenant.user.password.reset",
|
|
41
|
+
"tenant.role.create",
|
|
42
|
+
"tenant.role.list",
|
|
43
|
+
"tenant.role.update",
|
|
44
|
+
"tenant.role.delete",
|
|
45
|
+
"tenant.role.view",
|
|
46
|
+
"tenant.role.assign",
|
|
47
|
+
"tenant.role.revoke",
|
|
48
|
+
"tenant.security.policy.view",
|
|
49
|
+
"tenant.security.policy.manage",
|
|
50
|
+
"tenant.branding.manage",
|
|
51
|
+
"tenant.audit.view",
|
|
52
|
+
"retail.user.create",
|
|
53
|
+
"retail.user.create.lateral",
|
|
54
|
+
"retail.user.read",
|
|
55
|
+
"retail.user.update",
|
|
56
|
+
"retail.user.status",
|
|
57
|
+
"retail.user.delete",
|
|
58
|
+
"retail.user.password.reset",
|
|
59
|
+
"retail.user.mfa.reset",
|
|
60
|
+
"retail.product.create",
|
|
61
|
+
"retail.product.list",
|
|
62
|
+
"retail.product.view",
|
|
63
|
+
"retail.product.update",
|
|
64
|
+
"retail.product.delete",
|
|
65
|
+
"retail.product.mdm_config",
|
|
66
|
+
"retail.inventory.list",
|
|
67
|
+
"retail.inventory.view",
|
|
68
|
+
"retail.inventory.update",
|
|
69
|
+
"retail.sale.create",
|
|
70
|
+
"retail.sale.list",
|
|
71
|
+
"retail.sale.cancel",
|
|
72
|
+
"retail.store.manage",
|
|
73
|
+
"retail.retailer.manage",
|
|
74
|
+
"lend.credit.create",
|
|
75
|
+
"lend.credit.list",
|
|
76
|
+
"lend.credit.view",
|
|
77
|
+
"lend.credit.update",
|
|
78
|
+
"lend.credit.liquidate",
|
|
79
|
+
"lend.credit.restructure",
|
|
80
|
+
"lend.payment.apply",
|
|
81
|
+
"lend.payment.list",
|
|
82
|
+
"lend.payment.reverse",
|
|
83
|
+
"lend.installment.view",
|
|
84
|
+
"mdm.device.enroll",
|
|
85
|
+
"mdm.device.release",
|
|
86
|
+
"mdm.device.archive",
|
|
87
|
+
"mdm.device.deactivate",
|
|
88
|
+
"mdm.device.lock.manual",
|
|
89
|
+
"mdm.device.unlock.manual",
|
|
90
|
+
"mdm.device.pin_unlock",
|
|
91
|
+
"mdm.device.extend_validity",
|
|
92
|
+
"mdm.device.notify",
|
|
93
|
+
"mdm.device.status.view",
|
|
94
|
+
"mdm.operation_log.view",
|
|
95
|
+
"mdm.test",
|
|
96
|
+
"pay.transaction.view",
|
|
97
|
+
]
|
|
98
|
+
`;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Permission,
|
|
3
|
+
PERMISSION_BIT_ORDER,
|
|
4
|
+
PERMS_VERSION,
|
|
5
|
+
permissionsToBits,
|
|
6
|
+
bitsToPermissions,
|
|
7
|
+
} from '../../../../src/platformRbac/enums/Permission';
|
|
8
|
+
|
|
9
|
+
describe('PERMISSION_BIT_ORDER', () => {
|
|
10
|
+
it('contiene TODOS los valores del enum Permission', () => {
|
|
11
|
+
const enumVals = Object.values(Permission) as string[];
|
|
12
|
+
expect([...PERMISSION_BIT_ORDER].sort()).toEqual([...enumVals].sort());
|
|
13
|
+
});
|
|
14
|
+
it('append-only: snapshot del ORDEN COMPLETO (rompe ante cualquier reorden/inserción)', () => {
|
|
15
|
+
// Snapshot del array entero, NO un prefijo: un reorden del índice 11+ o una inserción
|
|
16
|
+
// intermedia desalinea todos los tokens emitidos. Si esto rompe, fue intencional → -u consciente.
|
|
17
|
+
expect(PERMISSION_BIT_ORDER).toMatchSnapshot();
|
|
18
|
+
});
|
|
19
|
+
it('PERMS_VERSION es número estable', () => {
|
|
20
|
+
expect(typeof PERMS_VERSION).toBe('number');
|
|
21
|
+
expect(PERMS_VERSION).toMatchSnapshot();
|
|
22
|
+
});
|
|
23
|
+
it('round-trip permisos ↔ bits', () => {
|
|
24
|
+
const perms = [
|
|
25
|
+
PERMISSION_BIT_ORDER[0],
|
|
26
|
+
PERMISSION_BIT_ORDER[5],
|
|
27
|
+
PERMISSION_BIT_ORDER[PERMISSION_BIT_ORDER.length - 1],
|
|
28
|
+
];
|
|
29
|
+
const bits = permissionsToBits(perms);
|
|
30
|
+
expect(typeof bits).toBe('string');
|
|
31
|
+
expect(new Set(bitsToPermissions(bits))).toEqual(new Set(perms));
|
|
32
|
+
});
|
|
33
|
+
it('bitsToPermissions tolera basura → []', () => {
|
|
34
|
+
expect(bitsToPermissions('')).toEqual([]);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -17,14 +17,14 @@ class CreateUserRequest {
|
|
|
17
17
|
exports.CreateUserRequest = CreateUserRequest;
|
|
18
18
|
__decorate([
|
|
19
19
|
(0, class_transformer_1.Expose)(),
|
|
20
|
+
(0, class_validator_1.IsOptional)(),
|
|
20
21
|
(0, class_validator_1.IsString)(),
|
|
21
|
-
(0, class_validator_1.IsNotEmpty)(),
|
|
22
22
|
__metadata("design:type", String)
|
|
23
23
|
], CreateUserRequest.prototype, "userPoolId", void 0);
|
|
24
24
|
__decorate([
|
|
25
25
|
(0, class_transformer_1.Expose)(),
|
|
26
|
+
(0, class_validator_1.IsOptional)(),
|
|
26
27
|
(0, class_validator_1.IsString)(),
|
|
27
|
-
(0, class_validator_1.IsNotEmpty)(),
|
|
28
28
|
__metadata("design:type", String)
|
|
29
29
|
], CreateUserRequest.prototype, "region", void 0);
|
|
30
30
|
__decorate([
|
package/bin/index.d.ts
CHANGED
|
@@ -74,6 +74,7 @@ export * as CirculoCredito from './circuloCredito';
|
|
|
74
74
|
export * as MilestoneBusiness from './milestone-business';
|
|
75
75
|
export * as Mdm from './mdm';
|
|
76
76
|
export * as MessagesConnector from './messagesConnector';
|
|
77
|
+
export * as TwilioConnector from './twilioConnector';
|
|
77
78
|
export * as CognitoBackofficeConnector from './cognitoBackofficeConnector';
|
|
78
79
|
export * as PlatformRbac from './platformRbac';
|
|
79
80
|
export * as Remittance from './remittance';
|
package/bin/index.js
CHANGED
|
@@ -37,7 +37,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.Company = exports.Services = exports.AccountIssuanceBusiness = exports.AppSelectionData = exports.Device = exports.Observations = exports.IssuanceBusiness = exports.Blacklist = exports.CentralPayments = exports.Helpdesk = exports.FiadoApiResponse = exports.Auth = exports.LegalDocumentsBusiness = exports.Role = exports.STPAccount = exports.RiskProfile = exports.FraudPreventionEngine = exports.BBVARst = exports.Stp = exports.BenefitCenter = exports.BankAccount = exports.P2pContact = exports.CreditContract = exports.Contract = exports.ProductCatalog = exports.ContactInfo = exports.TransactionAnalytics = exports.Transaction = exports.TransactionProcessor = exports.GenericMessage = exports.EventBridgeMessage = exports.SessionActivity = exports.NotificationMessages = exports.ServicePayment = exports.Header = exports.Identity = exports.Group = exports.File = exports.ExchangeRate = exports.Directory = exports.Currency = exports.Country = exports.Card = exports.Authentication = exports.App = exports.Address = exports.Beneficiary = exports.Activity = exports.Account = exports.Crypto = void 0;
|
|
40
|
-
exports.TotpSecurity = exports.WalletFunding = exports.Remittance = exports.PlatformRbac = exports.CognitoBackofficeConnector = exports.MessagesConnector = exports.Mdm = exports.MilestoneBusiness = exports.CirculoCredito = exports.CreditStatements = exports.Sentry = exports.AiEngine = exports.Funnel = exports.TeamsConnector = exports.PlatformErrorEvents = exports.CustomerFile = exports.CreditBackoffice = exports.CreditDashboard = exports.CreditEngine = exports.Credit = exports.ComissionBusiness = exports.ReferralBusiness = exports.ZendeskMessaging = exports.NotificationWS = exports.Event = exports.PayrollBusiness = exports.Cnbv = exports.DirectorySetting = exports.InvoiceCollector = exports.Collector = exports.Pricelist = void 0;
|
|
40
|
+
exports.TotpSecurity = exports.WalletFunding = exports.Remittance = exports.PlatformRbac = exports.CognitoBackofficeConnector = exports.TwilioConnector = exports.MessagesConnector = exports.Mdm = exports.MilestoneBusiness = exports.CirculoCredito = exports.CreditStatements = exports.Sentry = exports.AiEngine = exports.Funnel = exports.TeamsConnector = exports.PlatformErrorEvents = exports.CustomerFile = exports.CreditBackoffice = exports.CreditDashboard = exports.CreditEngine = exports.Credit = exports.ComissionBusiness = exports.ReferralBusiness = exports.ZendeskMessaging = exports.NotificationWS = exports.Event = exports.PayrollBusiness = exports.Cnbv = exports.DirectorySetting = exports.InvoiceCollector = exports.Collector = exports.Pricelist = void 0;
|
|
41
41
|
exports.Crypto = __importStar(require("./crypto"));
|
|
42
42
|
exports.Account = __importStar(require("./account"));
|
|
43
43
|
exports.Activity = __importStar(require("./activity"));
|
|
@@ -114,6 +114,7 @@ exports.CirculoCredito = __importStar(require("./circuloCredito"));
|
|
|
114
114
|
exports.MilestoneBusiness = __importStar(require("./milestone-business"));
|
|
115
115
|
exports.Mdm = __importStar(require("./mdm"));
|
|
116
116
|
exports.MessagesConnector = __importStar(require("./messagesConnector"));
|
|
117
|
+
exports.TwilioConnector = __importStar(require("./twilioConnector"));
|
|
117
118
|
exports.CognitoBackofficeConnector = __importStar(require("./cognitoBackofficeConnector"));
|
|
118
119
|
// PlatformRbac: módulo del lambda platform-rbac-business (Fase 0 SureKeep).
|
|
119
120
|
// Contiene Permission enum + AuthContext + RoleAssignmentInfo + PermissionScope +
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forma completa de un Milestone tal como lo persiste y devuelve el lambda
|
|
3
|
+
* `milestone-business`. Es la representación canónica del item de la tabla DDB
|
|
4
|
+
* `Milestones` expuesta a consumers server-to-server (api-invoker).
|
|
5
|
+
*
|
|
6
|
+
* `value` es metadata libre asociada al evento (objeto de forma variable).
|
|
7
|
+
* `createdAt` / `updatedAt` son epoch ms (Dynamoose `timestamps: true`).
|
|
8
|
+
*/
|
|
9
|
+
export interface Milestone {
|
|
10
|
+
/** Identificador único del milestone. Determinístico: `${directoryId}#${eventKey}`. */
|
|
11
|
+
id: string;
|
|
12
|
+
/** directoryId del usuario al que pertenece el evento. */
|
|
13
|
+
directoryId: string;
|
|
14
|
+
/** Fecha en la que ocurrió el evento (epoch en milisegundos). */
|
|
15
|
+
eventDate: number;
|
|
16
|
+
/** Llave que identifica el tipo de evento/milestone. */
|
|
17
|
+
eventKey: string;
|
|
18
|
+
/** Metadata libre asociada al milestone (objeto con forma variable). */
|
|
19
|
+
value?: Record<string, unknown>;
|
|
20
|
+
/** Epoch ms de creación (Dynamoose timestamps). */
|
|
21
|
+
createdAt?: number;
|
|
22
|
+
/** Epoch ms de última actualización (Dynamoose timestamps). */
|
|
23
|
+
updatedAt?: number;
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cota máxima de directoryIds aceptados por request en el endpoint batch
|
|
3
|
+
* `privateListMilestonesByDirectoryIds`. Protege contra fan-out excesivo
|
|
4
|
+
* (cada directoryId dispara un query GSI con drenado de paginación).
|
|
5
|
+
*/
|
|
6
|
+
export declare const MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH = 100;
|
|
7
|
+
/**
|
|
8
|
+
* Body de `POST /private/milestones/by-directory-ids`.
|
|
9
|
+
*
|
|
10
|
+
* Recibe una lista de directoryIds y devuelve, por cada uno, el array COMPLETO
|
|
11
|
+
* de milestones (paginación drenada del lado del lambda). Se usa POST en lugar
|
|
12
|
+
* de GET porque la lista puede ser larga y no cabe cómoda en query string.
|
|
13
|
+
*
|
|
14
|
+
* La cota de tamaño (`MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH`) se valida también
|
|
15
|
+
* en el manager para responder 400 explícito si se excede.
|
|
16
|
+
*/
|
|
17
|
+
export declare class MilestonesByDirectoryIdsRequest {
|
|
18
|
+
directoryIds: string[];
|
|
19
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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.MilestonesByDirectoryIdsRequest = exports.MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH = void 0;
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
/**
|
|
15
|
+
* Cota máxima de directoryIds aceptados por request en el endpoint batch
|
|
16
|
+
* `privateListMilestonesByDirectoryIds`. Protege contra fan-out excesivo
|
|
17
|
+
* (cada directoryId dispara un query GSI con drenado de paginación).
|
|
18
|
+
*/
|
|
19
|
+
exports.MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH = 100;
|
|
20
|
+
/**
|
|
21
|
+
* Body de `POST /private/milestones/by-directory-ids`.
|
|
22
|
+
*
|
|
23
|
+
* Recibe una lista de directoryIds y devuelve, por cada uno, el array COMPLETO
|
|
24
|
+
* de milestones (paginación drenada del lado del lambda). Se usa POST en lugar
|
|
25
|
+
* de GET porque la lista puede ser larga y no cabe cómoda en query string.
|
|
26
|
+
*
|
|
27
|
+
* La cota de tamaño (`MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH`) se valida también
|
|
28
|
+
* en el manager para responder 400 explícito si se excede.
|
|
29
|
+
*/
|
|
30
|
+
class MilestonesByDirectoryIdsRequest {
|
|
31
|
+
}
|
|
32
|
+
exports.MilestonesByDirectoryIdsRequest = MilestonesByDirectoryIdsRequest;
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, class_validator_1.IsArray)(),
|
|
35
|
+
(0, class_validator_1.ArrayNotEmpty)(),
|
|
36
|
+
(0, class_validator_1.ArrayMaxSize)(exports.MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH),
|
|
37
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
38
|
+
__metadata("design:type", Array)
|
|
39
|
+
], MilestonesByDirectoryIdsRequest.prototype, "directoryIds", void 0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Milestone } from "./Milestone";
|
|
2
|
+
/**
|
|
3
|
+
* Respuesta de `POST /private/milestones/by-directory-ids`.
|
|
4
|
+
*
|
|
5
|
+
* Mapa directoryId -> array COMPLETO de milestones de ese directorio.
|
|
6
|
+
* Cada directoryId solicitado aparece como clave; si un directorio no tiene
|
|
7
|
+
* milestones, su valor es un array vacío `[]` (la clave NO se omite, para que
|
|
8
|
+
* el consumer pueda distinguir "consultado, sin milestones" de "no consultado").
|
|
9
|
+
*/
|
|
10
|
+
export type MilestonesByDirectoryIdsResponse = Record<string, Milestone[]>;
|
|
@@ -1 +1,4 @@
|
|
|
1
1
|
export { MilestonesByEventKeyDateRangeParams } from "./dtos/MilestonesByEventKeyDateRangeParams";
|
|
2
|
+
export { Milestone } from "./dtos/Milestone";
|
|
3
|
+
export { MilestonesByDirectoryIdsRequest, MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH, } from "./dtos/MilestonesByDirectoryIdsRequest";
|
|
4
|
+
export { MilestonesByDirectoryIdsResponse } from "./dtos/MilestonesByDirectoryIdsResponse";
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH = exports.MilestonesByDirectoryIdsRequest = void 0;
|
|
4
|
+
var MilestonesByDirectoryIdsRequest_1 = require("./dtos/MilestonesByDirectoryIdsRequest");
|
|
5
|
+
Object.defineProperty(exports, "MilestonesByDirectoryIdsRequest", { enumerable: true, get: function () { return MilestonesByDirectoryIdsRequest_1.MilestonesByDirectoryIdsRequest; } });
|
|
6
|
+
Object.defineProperty(exports, "MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH", { enumerable: true, get: function () { return MilestonesByDirectoryIdsRequest_1.MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH; } });
|
|
@@ -18,4 +18,10 @@ export interface AuthContext {
|
|
|
18
18
|
permissions: Permission[];
|
|
19
19
|
resolvedAt: string;
|
|
20
20
|
issuer?: string;
|
|
21
|
+
/** Bitset base64url de permisos efectivos (token-as-cache). Ausente → fallback al resolver/claim. */
|
|
22
|
+
permBits?: string;
|
|
23
|
+
/** Versión del catálogo (PERMS_VERSION) con la que se construyó permBits. */
|
|
24
|
+
permVer?: number;
|
|
25
|
+
/** Epoch de permisos del tenant al momento de emitir el token. */
|
|
26
|
+
permsEpoch?: number;
|
|
21
27
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Permission } from '../enums/Permission';
|
|
2
|
+
import type { RoleAssignmentInfo } from './RoleAssignmentInfo';
|
|
3
|
+
/** Respuesta de platform-rbac-business /internal/effective-permissions (consumida por jwt-inyector). */
|
|
4
|
+
export interface EffectivePermissionsResponse {
|
|
5
|
+
permissions: Permission[];
|
|
6
|
+
roleAssignments: RoleAssignmentInfo[];
|
|
7
|
+
permsEpoch: number;
|
|
8
|
+
}
|
|
@@ -102,3 +102,16 @@ export declare enum Permission {
|
|
|
102
102
|
MDM_TEST = "mdm.test",
|
|
103
103
|
PAY_TRANSACTION_VIEW = "pay.transaction.view"
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
|
|
107
|
+
* Índice de cada permiso = su posición de bit. NUNCA reordenar ni borrar:
|
|
108
|
+
* deprecados CONSERVAN su posición; los nuevos van SIEMPRE al final.
|
|
109
|
+
* Derivado explícitamente (no Object.values, frágil ante edición del enum).
|
|
110
|
+
*/
|
|
111
|
+
export declare const PERMISSION_BIT_ORDER: readonly Permission[];
|
|
112
|
+
/** Versión del catálogo = hash del orden. Cambia solo si el orden cambia. */
|
|
113
|
+
export declare const PERMS_VERSION: number;
|
|
114
|
+
/** Comprime un set de permisos a bitset base64url. */
|
|
115
|
+
export declare function permissionsToBits(perms: readonly Permission[]): string;
|
|
116
|
+
/** Decodifica un bitset base64url a la lista de permisos. Tolerante a basura → []. */
|
|
117
|
+
export declare function bitsToPermissions(bits: string): Permission[];
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Permission = void 0;
|
|
3
|
+
exports.PERMS_VERSION = exports.PERMISSION_BIT_ORDER = exports.Permission = void 0;
|
|
4
|
+
exports.permissionsToBits = permissionsToBits;
|
|
5
|
+
exports.bitsToPermissions = bitsToPermissions;
|
|
4
6
|
/**
|
|
5
7
|
* Catálogo universal de permisos del sistema RBAC Fiado.
|
|
6
8
|
*
|
|
@@ -135,3 +137,140 @@ var Permission;
|
|
|
135
137
|
// ====================================================
|
|
136
138
|
Permission["PAY_TRANSACTION_VIEW"] = "pay.transaction.view";
|
|
137
139
|
})(Permission || (exports.Permission = Permission = {}));
|
|
140
|
+
/**
|
|
141
|
+
* Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
|
|
142
|
+
* Índice de cada permiso = su posición de bit. NUNCA reordenar ni borrar:
|
|
143
|
+
* deprecados CONSERVAN su posición; los nuevos van SIEMPRE al final.
|
|
144
|
+
* Derivado explícitamente (no Object.values, frágil ante edición del enum).
|
|
145
|
+
*/
|
|
146
|
+
exports.PERMISSION_BIT_ORDER = [
|
|
147
|
+
Permission.RBAC_CATALOG_MANAGE,
|
|
148
|
+
Permission.PLATFORM_TENANT_CREATE,
|
|
149
|
+
Permission.PLATFORM_TENANT_LIST,
|
|
150
|
+
Permission.PLATFORM_TENANT_VIEW,
|
|
151
|
+
Permission.PLATFORM_TENANT_UPDATE,
|
|
152
|
+
Permission.PLATFORM_TENANT_SUSPEND,
|
|
153
|
+
Permission.PLATFORM_TENANT_ACTIVATE,
|
|
154
|
+
Permission.PLATFORM_TENANT_ADMIN_REPLACE,
|
|
155
|
+
Permission.PLATFORM_COGNITO_POOL_MANAGE,
|
|
156
|
+
Permission.PLATFORM_COGNITO_POOL_LIST,
|
|
157
|
+
Permission.PLATFORM_USER_CREATE,
|
|
158
|
+
Permission.PLATFORM_USER_LIST,
|
|
159
|
+
Permission.PLATFORM_USER_VIEW,
|
|
160
|
+
Permission.PLATFORM_USER_UPDATE,
|
|
161
|
+
Permission.PLATFORM_USER_DISABLE,
|
|
162
|
+
Permission.PLATFORM_USER_ENABLE,
|
|
163
|
+
Permission.PLATFORM_USER_DELETE,
|
|
164
|
+
Permission.PLATFORM_ROLE_CREATE,
|
|
165
|
+
Permission.PLATFORM_ROLE_LIST,
|
|
166
|
+
Permission.PLATFORM_ROLE_UPDATE,
|
|
167
|
+
Permission.PLATFORM_ROLE_DELETE,
|
|
168
|
+
Permission.PLATFORM_AUDIT_VIEW,
|
|
169
|
+
Permission.TENANT_USER_CREATE,
|
|
170
|
+
Permission.TENANT_USER_CREATE_LATERAL,
|
|
171
|
+
Permission.TENANT_USER_READ,
|
|
172
|
+
Permission.TENANT_USER_STATUS,
|
|
173
|
+
Permission.TENANT_USER_LIST,
|
|
174
|
+
Permission.TENANT_USER_VIEW,
|
|
175
|
+
Permission.TENANT_USER_UPDATE,
|
|
176
|
+
Permission.TENANT_USER_DISABLE,
|
|
177
|
+
Permission.TENANT_USER_ENABLE,
|
|
178
|
+
Permission.TENANT_USER_DELETE,
|
|
179
|
+
Permission.TENANT_USER_MFA_RESET,
|
|
180
|
+
Permission.TENANT_USER_PASSWORD_RESET,
|
|
181
|
+
Permission.TENANT_ROLE_CREATE,
|
|
182
|
+
Permission.TENANT_ROLE_LIST,
|
|
183
|
+
Permission.TENANT_ROLE_UPDATE,
|
|
184
|
+
Permission.TENANT_ROLE_DELETE,
|
|
185
|
+
Permission.TENANT_ROLE_VIEW,
|
|
186
|
+
Permission.TENANT_ROLE_ASSIGN,
|
|
187
|
+
Permission.TENANT_ROLE_REVOKE,
|
|
188
|
+
Permission.TENANT_SECURITY_POLICY_VIEW,
|
|
189
|
+
Permission.TENANT_SECURITY_POLICY_MANAGE,
|
|
190
|
+
Permission.TENANT_BRANDING_MANAGE,
|
|
191
|
+
Permission.TENANT_AUDIT_VIEW,
|
|
192
|
+
Permission.RETAIL_USER_CREATE,
|
|
193
|
+
Permission.RETAIL_USER_CREATE_LATERAL,
|
|
194
|
+
Permission.RETAIL_USER_READ,
|
|
195
|
+
Permission.RETAIL_USER_UPDATE,
|
|
196
|
+
Permission.RETAIL_USER_STATUS,
|
|
197
|
+
Permission.RETAIL_USER_DELETE,
|
|
198
|
+
Permission.RETAIL_USER_PASSWORD_RESET,
|
|
199
|
+
Permission.RETAIL_USER_MFA_RESET,
|
|
200
|
+
Permission.RETAIL_PRODUCT_CREATE,
|
|
201
|
+
Permission.RETAIL_PRODUCT_LIST,
|
|
202
|
+
Permission.RETAIL_PRODUCT_VIEW,
|
|
203
|
+
Permission.RETAIL_PRODUCT_UPDATE,
|
|
204
|
+
Permission.RETAIL_PRODUCT_DELETE,
|
|
205
|
+
Permission.RETAIL_PRODUCT_MDM_CONFIG,
|
|
206
|
+
Permission.RETAIL_INVENTORY_LIST,
|
|
207
|
+
Permission.RETAIL_INVENTORY_VIEW,
|
|
208
|
+
Permission.RETAIL_INVENTORY_UPDATE,
|
|
209
|
+
Permission.RETAIL_SALE_CREATE,
|
|
210
|
+
Permission.RETAIL_SALE_LIST,
|
|
211
|
+
Permission.RETAIL_SALE_CANCEL,
|
|
212
|
+
Permission.RETAIL_STORE_MANAGE,
|
|
213
|
+
Permission.RETAIL_RETAILER_MANAGE,
|
|
214
|
+
Permission.LEND_CREDIT_CREATE,
|
|
215
|
+
Permission.LEND_CREDIT_LIST,
|
|
216
|
+
Permission.LEND_CREDIT_VIEW,
|
|
217
|
+
Permission.LEND_CREDIT_UPDATE,
|
|
218
|
+
Permission.LEND_CREDIT_LIQUIDATE,
|
|
219
|
+
Permission.LEND_CREDIT_RESTRUCTURE,
|
|
220
|
+
Permission.LEND_PAYMENT_APPLY,
|
|
221
|
+
Permission.LEND_PAYMENT_LIST,
|
|
222
|
+
Permission.LEND_PAYMENT_REVERSE,
|
|
223
|
+
Permission.LEND_INSTALLMENT_VIEW,
|
|
224
|
+
Permission.MDM_DEVICE_ENROLL,
|
|
225
|
+
Permission.MDM_DEVICE_RELEASE,
|
|
226
|
+
Permission.MDM_DEVICE_ARCHIVE,
|
|
227
|
+
Permission.MDM_DEVICE_DEACTIVATE,
|
|
228
|
+
Permission.MDM_DEVICE_LOCK_MANUAL,
|
|
229
|
+
Permission.MDM_DEVICE_UNLOCK_MANUAL,
|
|
230
|
+
Permission.MDM_DEVICE_PIN_UNLOCK,
|
|
231
|
+
Permission.MDM_DEVICE_EXTEND_VALIDITY,
|
|
232
|
+
Permission.MDM_DEVICE_NOTIFY,
|
|
233
|
+
Permission.MDM_DEVICE_STATUS_VIEW,
|
|
234
|
+
Permission.MDM_OPERATION_LOG_VIEW,
|
|
235
|
+
Permission.MDM_TEST,
|
|
236
|
+
Permission.PAY_TRANSACTION_VIEW,
|
|
237
|
+
];
|
|
238
|
+
function djb2(input) {
|
|
239
|
+
let h = 5381;
|
|
240
|
+
for (let i = 0; i < input.length; i++)
|
|
241
|
+
h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;
|
|
242
|
+
return h;
|
|
243
|
+
}
|
|
244
|
+
/** Versión del catálogo = hash del orden. Cambia solo si el orden cambia. */
|
|
245
|
+
exports.PERMS_VERSION = djb2(exports.PERMISSION_BIT_ORDER.join('|'));
|
|
246
|
+
const BIT_INDEX = new Map(exports.PERMISSION_BIT_ORDER.map((p, i) => [p, i]));
|
|
247
|
+
/** Comprime un set de permisos a bitset base64url. */
|
|
248
|
+
function permissionsToBits(perms) {
|
|
249
|
+
const bytes = new Uint8Array(Math.ceil(exports.PERMISSION_BIT_ORDER.length / 8));
|
|
250
|
+
for (const p of perms) {
|
|
251
|
+
const idx = BIT_INDEX.get(p);
|
|
252
|
+
if (idx === undefined)
|
|
253
|
+
continue;
|
|
254
|
+
bytes[idx >> 3] |= 1 << (idx & 7);
|
|
255
|
+
}
|
|
256
|
+
return Buffer.from(bytes).toString('base64url');
|
|
257
|
+
}
|
|
258
|
+
/** Decodifica un bitset base64url a la lista de permisos. Tolerante a basura → []. */
|
|
259
|
+
function bitsToPermissions(bits) {
|
|
260
|
+
if (typeof bits !== 'string' || bits.length === 0)
|
|
261
|
+
return [];
|
|
262
|
+
let bytes;
|
|
263
|
+
try {
|
|
264
|
+
bytes = Buffer.from(bits, 'base64url');
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return [];
|
|
268
|
+
}
|
|
269
|
+
const out = [];
|
|
270
|
+
for (let i = 0; i < exports.PERMISSION_BIT_ORDER.length; i++) {
|
|
271
|
+
const byte = bytes[i >> 3] ?? 0;
|
|
272
|
+
if (byte & (1 << (i & 7)))
|
|
273
|
+
out.push(exports.PERMISSION_BIT_ORDER[i]);
|
|
274
|
+
}
|
|
275
|
+
return out;
|
|
276
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export { Permission } from './enums/Permission';
|
|
1
|
+
export { Permission, PERMISSION_BIT_ORDER, PERMS_VERSION, permissionsToBits, bitsToPermissions, } from './enums/Permission';
|
|
2
2
|
export { PermissionScope } from './enums/PermissionScope';
|
|
3
3
|
export { PermissionCategory } from './enums/PermissionCategory';
|
|
4
4
|
export type { AuthContext } from './dtos/AuthContext';
|
|
5
5
|
export type { RoleAssignmentInfo } from './dtos/RoleAssignmentInfo';
|
|
6
6
|
export type { PermissionMeta } from './dtos/PermissionMeta';
|
|
7
|
+
export type { EffectivePermissionsResponse } from './dtos/EffectivePermissionsResponse';
|
|
7
8
|
export * from './enums/MfaMethodEnum';
|
|
8
9
|
export * from './enums/ChallengeNameEnum';
|
|
9
10
|
export * from './auth/DefineNextChallengeRequest';
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// del platform-rbac-business documenta la migración futura de los 4 símbolos cross-cutting
|
|
6
6
|
// (Permission, PermissionScope, AuthContext, RoleAssignmentInfo) de aquí a `rbac/`.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
// EffectivePermissionsResponse
|
|
10
|
-
//
|
|
8
|
+
// Los DTOs propios del rbac-business se van agregando a medida que los flujos los necesitan.
|
|
9
|
+
// EffectivePermissionsResponse ya vive acá (lo consume jwt-inyector vía /internal/effective-permissions).
|
|
10
|
+
// Otros DTOs aún pendientes se sumarán cuando los managers que los consumen se implementen.
|
|
11
11
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
12
|
if (k2 === undefined) k2 = k;
|
|
13
13
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -23,9 +23,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
23
23
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.scopeRankOrder = exports.tableSuffixForLevel = exports.levelsOf = exports.TENANT_TYPES = exports.TenantType = exports.AuthorizeDenyReason = exports.PermissionCategory = exports.PermissionScope = exports.Permission = void 0;
|
|
26
|
+
exports.scopeRankOrder = exports.tableSuffixForLevel = exports.levelsOf = exports.TENANT_TYPES = exports.TenantType = exports.AuthorizeDenyReason = exports.PermissionCategory = exports.PermissionScope = exports.bitsToPermissions = exports.permissionsToBits = exports.PERMS_VERSION = exports.PERMISSION_BIT_ORDER = exports.Permission = void 0;
|
|
27
27
|
var Permission_1 = require("./enums/Permission");
|
|
28
28
|
Object.defineProperty(exports, "Permission", { enumerable: true, get: function () { return Permission_1.Permission; } });
|
|
29
|
+
Object.defineProperty(exports, "PERMISSION_BIT_ORDER", { enumerable: true, get: function () { return Permission_1.PERMISSION_BIT_ORDER; } });
|
|
30
|
+
Object.defineProperty(exports, "PERMS_VERSION", { enumerable: true, get: function () { return Permission_1.PERMS_VERSION; } });
|
|
31
|
+
Object.defineProperty(exports, "permissionsToBits", { enumerable: true, get: function () { return Permission_1.permissionsToBits; } });
|
|
32
|
+
Object.defineProperty(exports, "bitsToPermissions", { enumerable: true, get: function () { return Permission_1.bitsToPermissions; } });
|
|
29
33
|
var PermissionScope_1 = require("./enums/PermissionScope");
|
|
30
34
|
Object.defineProperty(exports, "PermissionScope", { enumerable: true, get: function () { return PermissionScope_1.PermissionScope; } });
|
|
31
35
|
var PermissionCategory_1 = require("./enums/PermissionCategory");
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SelectedProvider } from './SelectedProvider';
|
|
2
|
+
/**
|
|
3
|
+
* Contrato de entrada `messages-business → twilio-connector`.
|
|
4
|
+
*
|
|
5
|
+
* messages-business resuelve el proveedor (plantilla, remitente, `secretRef`)
|
|
6
|
+
* desde el `senderConfig` del `(tenant, channel)` y lo manda ya resuelto en
|
|
7
|
+
* `selectedProvider`. El connector NO resuelve plantillas ni elige proveedor:
|
|
8
|
+
* solo transmite a Twilio y resuelve el secret indicado por `secretRef`.
|
|
9
|
+
*
|
|
10
|
+
* NOTA: `channelType` es `string` (no el enum) a proposito: el connector es un
|
|
11
|
+
* transporte tonto y maneja canales como WHATSAPP que aun no estan en
|
|
12
|
+
* `DeliveryChannelEnum`. El alta de WHATSAPP en el enum aplica al lado *inbound*
|
|
13
|
+
* (productor → messages-business), no a este contrato. Ver docs/cross-team en
|
|
14
|
+
* messages-business.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ConnectorSendMessageRequest {
|
|
17
|
+
/** Canal de entrega. Ej: "WHATSAPP", "SMS". */
|
|
18
|
+
channelType: string;
|
|
19
|
+
/** Numero destino en formato E.164. Ej: "+50212345678". */
|
|
20
|
+
destination: string;
|
|
21
|
+
/** Tipo de mensaje de dominio. Ej: "OTP_CODE". Solo para logging/trazabilidad. */
|
|
22
|
+
messageType?: string;
|
|
23
|
+
/** Idioma de la plantilla. Ej: "ES". Solo para logging/trazabilidad. */
|
|
24
|
+
language?: string;
|
|
25
|
+
/** Proveedor ya seleccionado y resuelto por messages-business. */
|
|
26
|
+
selectedProvider: SelectedProvider;
|
|
27
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
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.ConnectorSendMessageRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const SelectedProvider_1 = require("./SelectedProvider");
|
|
16
|
+
/**
|
|
17
|
+
* Contrato de entrada `messages-business → twilio-connector`.
|
|
18
|
+
*
|
|
19
|
+
* messages-business resuelve el proveedor (plantilla, remitente, `secretRef`)
|
|
20
|
+
* desde el `senderConfig` del `(tenant, channel)` y lo manda ya resuelto en
|
|
21
|
+
* `selectedProvider`. El connector NO resuelve plantillas ni elige proveedor:
|
|
22
|
+
* solo transmite a Twilio y resuelve el secret indicado por `secretRef`.
|
|
23
|
+
*
|
|
24
|
+
* NOTA: `channelType` es `string` (no el enum) a proposito: el connector es un
|
|
25
|
+
* transporte tonto y maneja canales como WHATSAPP que aun no estan en
|
|
26
|
+
* `DeliveryChannelEnum`. El alta de WHATSAPP en el enum aplica al lado *inbound*
|
|
27
|
+
* (productor → messages-business), no a este contrato. Ver docs/cross-team en
|
|
28
|
+
* messages-business.
|
|
29
|
+
*/
|
|
30
|
+
class ConnectorSendMessageRequest {
|
|
31
|
+
}
|
|
32
|
+
exports.ConnectorSendMessageRequest = ConnectorSendMessageRequest;
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, class_transformer_1.Expose)(),
|
|
35
|
+
(0, class_validator_1.IsString)(),
|
|
36
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], ConnectorSendMessageRequest.prototype, "channelType", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, class_transformer_1.Expose)(),
|
|
41
|
+
(0, class_validator_1.IsString)(),
|
|
42
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], ConnectorSendMessageRequest.prototype, "destination", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, class_transformer_1.Expose)(),
|
|
47
|
+
(0, class_validator_1.IsOptional)(),
|
|
48
|
+
(0, class_validator_1.IsString)(),
|
|
49
|
+
__metadata("design:type", String)
|
|
50
|
+
], ConnectorSendMessageRequest.prototype, "messageType", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, class_transformer_1.Expose)(),
|
|
53
|
+
(0, class_validator_1.IsOptional)(),
|
|
54
|
+
(0, class_validator_1.IsString)(),
|
|
55
|
+
__metadata("design:type", String)
|
|
56
|
+
], ConnectorSendMessageRequest.prototype, "language", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, class_transformer_1.Expose)(),
|
|
59
|
+
(0, class_validator_1.ValidateNested)(),
|
|
60
|
+
(0, class_transformer_1.Type)(() => SelectedProvider_1.SelectedProvider),
|
|
61
|
+
__metadata("design:type", SelectedProvider_1.SelectedProvider)
|
|
62
|
+
], ConnectorSendMessageRequest.prototype, "selectedProvider", void 0);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Respuesta del twilio-connector tras delegar el envio a Twilio.
|
|
3
|
+
*/
|
|
4
|
+
export declare class ConnectorSendMessageResponse {
|
|
5
|
+
/** SID del mensaje generado por Twilio. */
|
|
6
|
+
providerMessageId: string;
|
|
7
|
+
/** Estado reportado por Twilio al momento del envio (queued, sent, ...). */
|
|
8
|
+
status: string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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.ConnectorSendMessageResponse = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* Respuesta del twilio-connector tras delegar el envio a Twilio.
|
|
17
|
+
*/
|
|
18
|
+
class ConnectorSendMessageResponse {
|
|
19
|
+
}
|
|
20
|
+
exports.ConnectorSendMessageResponse = ConnectorSendMessageResponse;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_transformer_1.Expose)(),
|
|
23
|
+
(0, class_validator_1.IsString)(),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], ConnectorSendMessageResponse.prototype, "providerMessageId", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, class_transformer_1.Expose)(),
|
|
28
|
+
(0, class_validator_1.IsString)(),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], ConnectorSendMessageResponse.prototype, "status", void 0);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proveedor ya resuelto por messages-business desde el `senderConfig` del
|
|
3
|
+
* `(tenant, channel)`. El twilio-connector es transporte tonto: solo transmite
|
|
4
|
+
* estos valores a Twilio. Los nombres son genericos para no acoplar el contrato
|
|
5
|
+
* al vocabulario del proveedor.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SelectedProvider {
|
|
8
|
+
/** Plantilla del proveedor ya resuelta. Para Twilio se traduce a `contentSid` (HX...). */
|
|
9
|
+
templateId: string;
|
|
10
|
+
/** Remitente ya resuelto. Para Twilio = Messaging Service SID (MG...) o numero `from`. */
|
|
11
|
+
senderId: string;
|
|
12
|
+
/** Variables de la plantilla ya resueltas, keyeadas por slot posicional. Ej: { "1": "1234" }. */
|
|
13
|
+
contentVariables?: Record<string, string>;
|
|
14
|
+
/**
|
|
15
|
+
* Referencia (nombre/ARN) al secret de Secrets Manager con las credenciales
|
|
16
|
+
* de la cuenta de Twilio de este `(tenant, channel)`. Ej: "twilio/FIADO/credentials".
|
|
17
|
+
* El connector resuelve el secret real con esta referencia justo antes de enviar.
|
|
18
|
+
* Opcional: si se omite, el connector usa su secret por defecto (TWILIO_SECRET_NAME).
|
|
19
|
+
*/
|
|
20
|
+
secretRef?: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
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.SelectedProvider = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/**
|
|
16
|
+
* Proveedor ya resuelto por messages-business desde el `senderConfig` del
|
|
17
|
+
* `(tenant, channel)`. El twilio-connector es transporte tonto: solo transmite
|
|
18
|
+
* estos valores a Twilio. Los nombres son genericos para no acoplar el contrato
|
|
19
|
+
* al vocabulario del proveedor.
|
|
20
|
+
*/
|
|
21
|
+
class SelectedProvider {
|
|
22
|
+
}
|
|
23
|
+
exports.SelectedProvider = SelectedProvider;
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, class_transformer_1.Expose)(),
|
|
26
|
+
(0, class_validator_1.IsString)(),
|
|
27
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
28
|
+
__metadata("design:type", String)
|
|
29
|
+
], SelectedProvider.prototype, "templateId", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, class_transformer_1.Expose)(),
|
|
32
|
+
(0, class_validator_1.IsString)(),
|
|
33
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
34
|
+
__metadata("design:type", String)
|
|
35
|
+
], SelectedProvider.prototype, "senderId", void 0);
|
|
36
|
+
__decorate([
|
|
37
|
+
(0, class_transformer_1.Expose)(),
|
|
38
|
+
(0, class_validator_1.IsOptional)(),
|
|
39
|
+
(0, class_validator_1.IsObject)(),
|
|
40
|
+
__metadata("design:type", Object)
|
|
41
|
+
], SelectedProvider.prototype, "contentVariables", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
(0, class_transformer_1.Expose)(),
|
|
44
|
+
(0, class_validator_1.IsOptional)(),
|
|
45
|
+
(0, class_validator_1.IsString)(),
|
|
46
|
+
__metadata("design:type", String)
|
|
47
|
+
], SelectedProvider.prototype, "secretRef", void 0);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./dtos/SelectedProvider"), exports);
|
|
18
|
+
__exportStar(require("./dtos/ConnectorSendMessageRequest"), exports);
|
|
19
|
+
__exportStar(require("./dtos/ConnectorSendMessageResponse"), exports);
|
package/package.json
CHANGED
|
@@ -2,8 +2,11 @@ import { Expose } from 'class-transformer';
|
|
|
2
2
|
import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
|
3
3
|
|
|
4
4
|
export class CreateUserRequest {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
// userPoolId + region son OPCIONALES: el alta de usuario PLATFORM ya no los manda desde el front
|
|
6
|
+
// (el backend platform-rbac-business los resuelve de la config del tenant 'platform'). Se conservan
|
|
7
|
+
// en el DTO porque los demás callers del connector SÍ los proveen.
|
|
8
|
+
@Expose() @IsOptional() @IsString() userPoolId?: string;
|
|
9
|
+
@Expose() @IsOptional() @IsString() region?: string;
|
|
7
10
|
@Expose() @IsEmail() email!: string;
|
|
8
11
|
@Expose() @IsOptional() @IsString() displayName?: string;
|
|
9
12
|
@Expose() @IsString() @IsNotEmpty() tenantId!: string;
|
package/src/index.ts
CHANGED
|
@@ -74,6 +74,7 @@ export * as CirculoCredito from './circuloCredito';
|
|
|
74
74
|
export * as MilestoneBusiness from './milestone-business';
|
|
75
75
|
export * as Mdm from './mdm';
|
|
76
76
|
export * as MessagesConnector from './messagesConnector';
|
|
77
|
+
export * as TwilioConnector from './twilioConnector';
|
|
77
78
|
export * as CognitoBackofficeConnector from './cognitoBackofficeConnector';
|
|
78
79
|
// PlatformRbac: módulo del lambda platform-rbac-business (Fase 0 SureKeep).
|
|
79
80
|
// Contiene Permission enum + AuthContext + RoleAssignmentInfo + PermissionScope +
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forma completa de un Milestone tal como lo persiste y devuelve el lambda
|
|
3
|
+
* `milestone-business`. Es la representación canónica del item de la tabla DDB
|
|
4
|
+
* `Milestones` expuesta a consumers server-to-server (api-invoker).
|
|
5
|
+
*
|
|
6
|
+
* `value` es metadata libre asociada al evento (objeto de forma variable).
|
|
7
|
+
* `createdAt` / `updatedAt` son epoch ms (Dynamoose `timestamps: true`).
|
|
8
|
+
*/
|
|
9
|
+
export interface Milestone {
|
|
10
|
+
/** Identificador único del milestone. Determinístico: `${directoryId}#${eventKey}`. */
|
|
11
|
+
id: string;
|
|
12
|
+
/** directoryId del usuario al que pertenece el evento. */
|
|
13
|
+
directoryId: string;
|
|
14
|
+
/** Fecha en la que ocurrió el evento (epoch en milisegundos). */
|
|
15
|
+
eventDate: number;
|
|
16
|
+
/** Llave que identifica el tipo de evento/milestone. */
|
|
17
|
+
eventKey: string;
|
|
18
|
+
/** Metadata libre asociada al milestone (objeto con forma variable). */
|
|
19
|
+
value?: Record<string, unknown>;
|
|
20
|
+
/** Epoch ms de creación (Dynamoose timestamps). */
|
|
21
|
+
createdAt?: number;
|
|
22
|
+
/** Epoch ms de última actualización (Dynamoose timestamps). */
|
|
23
|
+
updatedAt?: number;
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ArrayMaxSize, ArrayNotEmpty, IsArray, IsString } from "class-validator";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cota máxima de directoryIds aceptados por request en el endpoint batch
|
|
5
|
+
* `privateListMilestonesByDirectoryIds`. Protege contra fan-out excesivo
|
|
6
|
+
* (cada directoryId dispara un query GSI con drenado de paginación).
|
|
7
|
+
*/
|
|
8
|
+
export const MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH = 100;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Body de `POST /private/milestones/by-directory-ids`.
|
|
12
|
+
*
|
|
13
|
+
* Recibe una lista de directoryIds y devuelve, por cada uno, el array COMPLETO
|
|
14
|
+
* de milestones (paginación drenada del lado del lambda). Se usa POST en lugar
|
|
15
|
+
* de GET porque la lista puede ser larga y no cabe cómoda en query string.
|
|
16
|
+
*
|
|
17
|
+
* La cota de tamaño (`MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH`) se valida también
|
|
18
|
+
* en el manager para responder 400 explícito si se excede.
|
|
19
|
+
*/
|
|
20
|
+
export class MilestonesByDirectoryIdsRequest {
|
|
21
|
+
@IsArray()
|
|
22
|
+
@ArrayNotEmpty()
|
|
23
|
+
@ArrayMaxSize(MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH)
|
|
24
|
+
@IsString({ each: true })
|
|
25
|
+
directoryIds!: string[];
|
|
26
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Milestone } from "./Milestone";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Respuesta de `POST /private/milestones/by-directory-ids`.
|
|
5
|
+
*
|
|
6
|
+
* Mapa directoryId -> array COMPLETO de milestones de ese directorio.
|
|
7
|
+
* Cada directoryId solicitado aparece como clave; si un directorio no tiene
|
|
8
|
+
* milestones, su valor es un array vacío `[]` (la clave NO se omite, para que
|
|
9
|
+
* el consumer pueda distinguir "consultado, sin milestones" de "no consultado").
|
|
10
|
+
*/
|
|
11
|
+
export type MilestonesByDirectoryIdsResponse = Record<string, Milestone[]>;
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
// dtos
|
|
2
2
|
export { MilestonesByEventKeyDateRangeParams } from "./dtos/MilestonesByEventKeyDateRangeParams";
|
|
3
|
+
export { Milestone } from "./dtos/Milestone";
|
|
4
|
+
export {
|
|
5
|
+
MilestonesByDirectoryIdsRequest,
|
|
6
|
+
MILESTONES_BY_DIRECTORY_IDS_MAX_BATCH,
|
|
7
|
+
} from "./dtos/MilestonesByDirectoryIdsRequest";
|
|
8
|
+
export { MilestonesByDirectoryIdsResponse } from "./dtos/MilestonesByDirectoryIdsResponse";
|
|
@@ -19,4 +19,10 @@ export interface AuthContext {
|
|
|
19
19
|
permissions: Permission[];
|
|
20
20
|
resolvedAt: string;
|
|
21
21
|
issuer?: string;
|
|
22
|
+
/** Bitset base64url de permisos efectivos (token-as-cache). Ausente → fallback al resolver/claim. */
|
|
23
|
+
permBits?: string;
|
|
24
|
+
/** Versión del catálogo (PERMS_VERSION) con la que se construyó permBits. */
|
|
25
|
+
permVer?: number;
|
|
26
|
+
/** Epoch de permisos del tenant al momento de emitir el token. */
|
|
27
|
+
permsEpoch?: number;
|
|
22
28
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Permission } from '../enums/Permission';
|
|
2
|
+
import type { RoleAssignmentInfo } from './RoleAssignmentInfo';
|
|
3
|
+
|
|
4
|
+
/** Respuesta de platform-rbac-business /internal/effective-permissions (consumida por jwt-inyector). */
|
|
5
|
+
export interface EffectivePermissionsResponse {
|
|
6
|
+
permissions: Permission[];
|
|
7
|
+
roleAssignments: RoleAssignmentInfo[];
|
|
8
|
+
permsEpoch: number;
|
|
9
|
+
}
|
|
@@ -137,3 +137,139 @@ export enum Permission {
|
|
|
137
137
|
// ====================================================
|
|
138
138
|
PAY_TRANSACTION_VIEW = 'pay.transaction.view',
|
|
139
139
|
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
|
|
143
|
+
* Índice de cada permiso = su posición de bit. NUNCA reordenar ni borrar:
|
|
144
|
+
* deprecados CONSERVAN su posición; los nuevos van SIEMPRE al final.
|
|
145
|
+
* Derivado explícitamente (no Object.values, frágil ante edición del enum).
|
|
146
|
+
*/
|
|
147
|
+
export const PERMISSION_BIT_ORDER: readonly Permission[] = [
|
|
148
|
+
Permission.RBAC_CATALOG_MANAGE,
|
|
149
|
+
Permission.PLATFORM_TENANT_CREATE,
|
|
150
|
+
Permission.PLATFORM_TENANT_LIST,
|
|
151
|
+
Permission.PLATFORM_TENANT_VIEW,
|
|
152
|
+
Permission.PLATFORM_TENANT_UPDATE,
|
|
153
|
+
Permission.PLATFORM_TENANT_SUSPEND,
|
|
154
|
+
Permission.PLATFORM_TENANT_ACTIVATE,
|
|
155
|
+
Permission.PLATFORM_TENANT_ADMIN_REPLACE,
|
|
156
|
+
Permission.PLATFORM_COGNITO_POOL_MANAGE,
|
|
157
|
+
Permission.PLATFORM_COGNITO_POOL_LIST,
|
|
158
|
+
Permission.PLATFORM_USER_CREATE,
|
|
159
|
+
Permission.PLATFORM_USER_LIST,
|
|
160
|
+
Permission.PLATFORM_USER_VIEW,
|
|
161
|
+
Permission.PLATFORM_USER_UPDATE,
|
|
162
|
+
Permission.PLATFORM_USER_DISABLE,
|
|
163
|
+
Permission.PLATFORM_USER_ENABLE,
|
|
164
|
+
Permission.PLATFORM_USER_DELETE,
|
|
165
|
+
Permission.PLATFORM_ROLE_CREATE,
|
|
166
|
+
Permission.PLATFORM_ROLE_LIST,
|
|
167
|
+
Permission.PLATFORM_ROLE_UPDATE,
|
|
168
|
+
Permission.PLATFORM_ROLE_DELETE,
|
|
169
|
+
Permission.PLATFORM_AUDIT_VIEW,
|
|
170
|
+
Permission.TENANT_USER_CREATE,
|
|
171
|
+
Permission.TENANT_USER_CREATE_LATERAL,
|
|
172
|
+
Permission.TENANT_USER_READ,
|
|
173
|
+
Permission.TENANT_USER_STATUS,
|
|
174
|
+
Permission.TENANT_USER_LIST,
|
|
175
|
+
Permission.TENANT_USER_VIEW,
|
|
176
|
+
Permission.TENANT_USER_UPDATE,
|
|
177
|
+
Permission.TENANT_USER_DISABLE,
|
|
178
|
+
Permission.TENANT_USER_ENABLE,
|
|
179
|
+
Permission.TENANT_USER_DELETE,
|
|
180
|
+
Permission.TENANT_USER_MFA_RESET,
|
|
181
|
+
Permission.TENANT_USER_PASSWORD_RESET,
|
|
182
|
+
Permission.TENANT_ROLE_CREATE,
|
|
183
|
+
Permission.TENANT_ROLE_LIST,
|
|
184
|
+
Permission.TENANT_ROLE_UPDATE,
|
|
185
|
+
Permission.TENANT_ROLE_DELETE,
|
|
186
|
+
Permission.TENANT_ROLE_VIEW,
|
|
187
|
+
Permission.TENANT_ROLE_ASSIGN,
|
|
188
|
+
Permission.TENANT_ROLE_REVOKE,
|
|
189
|
+
Permission.TENANT_SECURITY_POLICY_VIEW,
|
|
190
|
+
Permission.TENANT_SECURITY_POLICY_MANAGE,
|
|
191
|
+
Permission.TENANT_BRANDING_MANAGE,
|
|
192
|
+
Permission.TENANT_AUDIT_VIEW,
|
|
193
|
+
Permission.RETAIL_USER_CREATE,
|
|
194
|
+
Permission.RETAIL_USER_CREATE_LATERAL,
|
|
195
|
+
Permission.RETAIL_USER_READ,
|
|
196
|
+
Permission.RETAIL_USER_UPDATE,
|
|
197
|
+
Permission.RETAIL_USER_STATUS,
|
|
198
|
+
Permission.RETAIL_USER_DELETE,
|
|
199
|
+
Permission.RETAIL_USER_PASSWORD_RESET,
|
|
200
|
+
Permission.RETAIL_USER_MFA_RESET,
|
|
201
|
+
Permission.RETAIL_PRODUCT_CREATE,
|
|
202
|
+
Permission.RETAIL_PRODUCT_LIST,
|
|
203
|
+
Permission.RETAIL_PRODUCT_VIEW,
|
|
204
|
+
Permission.RETAIL_PRODUCT_UPDATE,
|
|
205
|
+
Permission.RETAIL_PRODUCT_DELETE,
|
|
206
|
+
Permission.RETAIL_PRODUCT_MDM_CONFIG,
|
|
207
|
+
Permission.RETAIL_INVENTORY_LIST,
|
|
208
|
+
Permission.RETAIL_INVENTORY_VIEW,
|
|
209
|
+
Permission.RETAIL_INVENTORY_UPDATE,
|
|
210
|
+
Permission.RETAIL_SALE_CREATE,
|
|
211
|
+
Permission.RETAIL_SALE_LIST,
|
|
212
|
+
Permission.RETAIL_SALE_CANCEL,
|
|
213
|
+
Permission.RETAIL_STORE_MANAGE,
|
|
214
|
+
Permission.RETAIL_RETAILER_MANAGE,
|
|
215
|
+
Permission.LEND_CREDIT_CREATE,
|
|
216
|
+
Permission.LEND_CREDIT_LIST,
|
|
217
|
+
Permission.LEND_CREDIT_VIEW,
|
|
218
|
+
Permission.LEND_CREDIT_UPDATE,
|
|
219
|
+
Permission.LEND_CREDIT_LIQUIDATE,
|
|
220
|
+
Permission.LEND_CREDIT_RESTRUCTURE,
|
|
221
|
+
Permission.LEND_PAYMENT_APPLY,
|
|
222
|
+
Permission.LEND_PAYMENT_LIST,
|
|
223
|
+
Permission.LEND_PAYMENT_REVERSE,
|
|
224
|
+
Permission.LEND_INSTALLMENT_VIEW,
|
|
225
|
+
Permission.MDM_DEVICE_ENROLL,
|
|
226
|
+
Permission.MDM_DEVICE_RELEASE,
|
|
227
|
+
Permission.MDM_DEVICE_ARCHIVE,
|
|
228
|
+
Permission.MDM_DEVICE_DEACTIVATE,
|
|
229
|
+
Permission.MDM_DEVICE_LOCK_MANUAL,
|
|
230
|
+
Permission.MDM_DEVICE_UNLOCK_MANUAL,
|
|
231
|
+
Permission.MDM_DEVICE_PIN_UNLOCK,
|
|
232
|
+
Permission.MDM_DEVICE_EXTEND_VALIDITY,
|
|
233
|
+
Permission.MDM_DEVICE_NOTIFY,
|
|
234
|
+
Permission.MDM_DEVICE_STATUS_VIEW,
|
|
235
|
+
Permission.MDM_OPERATION_LOG_VIEW,
|
|
236
|
+
Permission.MDM_TEST,
|
|
237
|
+
Permission.PAY_TRANSACTION_VIEW,
|
|
238
|
+
] as const;
|
|
239
|
+
|
|
240
|
+
function djb2(input: string): number {
|
|
241
|
+
let h = 5381;
|
|
242
|
+
for (let i = 0; i < input.length; i++) h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;
|
|
243
|
+
return h;
|
|
244
|
+
}
|
|
245
|
+
/** Versión del catálogo = hash del orden. Cambia solo si el orden cambia. */
|
|
246
|
+
export const PERMS_VERSION: number = djb2(PERMISSION_BIT_ORDER.join('|'));
|
|
247
|
+
|
|
248
|
+
const BIT_INDEX: ReadonlyMap<Permission, number> = new Map(PERMISSION_BIT_ORDER.map((p, i) => [p, i]));
|
|
249
|
+
|
|
250
|
+
/** Comprime un set de permisos a bitset base64url. */
|
|
251
|
+
export function permissionsToBits(perms: readonly Permission[]): string {
|
|
252
|
+
const bytes = new Uint8Array(Math.ceil(PERMISSION_BIT_ORDER.length / 8));
|
|
253
|
+
for (const p of perms) {
|
|
254
|
+
const idx = BIT_INDEX.get(p);
|
|
255
|
+
if (idx === undefined) continue;
|
|
256
|
+
bytes[idx >> 3] |= 1 << (idx & 7);
|
|
257
|
+
}
|
|
258
|
+
return Buffer.from(bytes).toString('base64url');
|
|
259
|
+
}
|
|
260
|
+
/** Decodifica un bitset base64url a la lista de permisos. Tolerante a basura → []. */
|
|
261
|
+
export function bitsToPermissions(bits: string): Permission[] {
|
|
262
|
+
if (typeof bits !== 'string' || bits.length === 0) return [];
|
|
263
|
+
let bytes: Buffer;
|
|
264
|
+
try {
|
|
265
|
+
bytes = Buffer.from(bits, 'base64url');
|
|
266
|
+
} catch {
|
|
267
|
+
return [];
|
|
268
|
+
}
|
|
269
|
+
const out: Permission[] = [];
|
|
270
|
+
for (let i = 0; i < PERMISSION_BIT_ORDER.length; i++) {
|
|
271
|
+
const byte = bytes[i >> 3] ?? 0;
|
|
272
|
+
if (byte & (1 << (i & 7))) out.push(PERMISSION_BIT_ORDER[i]);
|
|
273
|
+
}
|
|
274
|
+
return out;
|
|
275
|
+
}
|
|
@@ -4,17 +4,24 @@
|
|
|
4
4
|
// del platform-rbac-business documenta la migración futura de los 4 símbolos cross-cutting
|
|
5
5
|
// (Permission, PermissionScope, AuthContext, RoleAssignmentInfo) de aquí a `rbac/`.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
// EffectivePermissionsResponse
|
|
9
|
-
//
|
|
7
|
+
// Los DTOs propios del rbac-business se van agregando a medida que los flujos los necesitan.
|
|
8
|
+
// EffectivePermissionsResponse ya vive acá (lo consume jwt-inyector vía /internal/effective-permissions).
|
|
9
|
+
// Otros DTOs aún pendientes se sumarán cuando los managers que los consumen se implementen.
|
|
10
10
|
|
|
11
|
-
export {
|
|
11
|
+
export {
|
|
12
|
+
Permission,
|
|
13
|
+
PERMISSION_BIT_ORDER,
|
|
14
|
+
PERMS_VERSION,
|
|
15
|
+
permissionsToBits,
|
|
16
|
+
bitsToPermissions,
|
|
17
|
+
} from './enums/Permission';
|
|
12
18
|
export { PermissionScope } from './enums/PermissionScope';
|
|
13
19
|
export { PermissionCategory } from './enums/PermissionCategory';
|
|
14
20
|
|
|
15
21
|
export type { AuthContext } from './dtos/AuthContext';
|
|
16
22
|
export type { RoleAssignmentInfo } from './dtos/RoleAssignmentInfo';
|
|
17
23
|
export type { PermissionMeta } from './dtos/PermissionMeta';
|
|
24
|
+
export type { EffectivePermissionsResponse } from './dtos/EffectivePermissionsResponse';
|
|
18
25
|
|
|
19
26
|
// Fase 1 — Custom Auth Challenge (Email OTP + TOTP) + MFA self-service.
|
|
20
27
|
// Class values (no type-only) — los DTOs llevan decoradores class-validator y se hidratan con plainToInstance en runtime.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Expose, Type } from 'class-transformer';
|
|
2
|
+
import { IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator';
|
|
3
|
+
import { SelectedProvider } from './SelectedProvider';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Contrato de entrada `messages-business → twilio-connector`.
|
|
7
|
+
*
|
|
8
|
+
* messages-business resuelve el proveedor (plantilla, remitente, `secretRef`)
|
|
9
|
+
* desde el `senderConfig` del `(tenant, channel)` y lo manda ya resuelto en
|
|
10
|
+
* `selectedProvider`. El connector NO resuelve plantillas ni elige proveedor:
|
|
11
|
+
* solo transmite a Twilio y resuelve el secret indicado por `secretRef`.
|
|
12
|
+
*
|
|
13
|
+
* NOTA: `channelType` es `string` (no el enum) a proposito: el connector es un
|
|
14
|
+
* transporte tonto y maneja canales como WHATSAPP que aun no estan en
|
|
15
|
+
* `DeliveryChannelEnum`. El alta de WHATSAPP en el enum aplica al lado *inbound*
|
|
16
|
+
* (productor → messages-business), no a este contrato. Ver docs/cross-team en
|
|
17
|
+
* messages-business.
|
|
18
|
+
*/
|
|
19
|
+
export class ConnectorSendMessageRequest {
|
|
20
|
+
/** Canal de entrega. Ej: "WHATSAPP", "SMS". */
|
|
21
|
+
@Expose() @IsString() @IsNotEmpty() channelType!: string;
|
|
22
|
+
|
|
23
|
+
/** Numero destino en formato E.164. Ej: "+50212345678". */
|
|
24
|
+
@Expose() @IsString() @IsNotEmpty() destination!: string;
|
|
25
|
+
|
|
26
|
+
/** Tipo de mensaje de dominio. Ej: "OTP_CODE". Solo para logging/trazabilidad. */
|
|
27
|
+
@Expose() @IsOptional() @IsString() messageType?: string;
|
|
28
|
+
|
|
29
|
+
/** Idioma de la plantilla. Ej: "ES". Solo para logging/trazabilidad. */
|
|
30
|
+
@Expose() @IsOptional() @IsString() language?: string;
|
|
31
|
+
|
|
32
|
+
/** Proveedor ya seleccionado y resuelto por messages-business. */
|
|
33
|
+
@Expose() @ValidateNested() @Type(() => SelectedProvider) selectedProvider!: SelectedProvider;
|
|
34
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsString } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Respuesta del twilio-connector tras delegar el envio a Twilio.
|
|
6
|
+
*/
|
|
7
|
+
export class ConnectorSendMessageResponse {
|
|
8
|
+
/** SID del mensaje generado por Twilio. */
|
|
9
|
+
@Expose() @IsString() providerMessageId!: string;
|
|
10
|
+
|
|
11
|
+
/** Estado reportado por Twilio al momento del envio (queued, sent, ...). */
|
|
12
|
+
@Expose() @IsString() status!: string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { IsNotEmpty, IsObject, IsOptional, IsString } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Proveedor ya resuelto por messages-business desde el `senderConfig` del
|
|
6
|
+
* `(tenant, channel)`. El twilio-connector es transporte tonto: solo transmite
|
|
7
|
+
* estos valores a Twilio. Los nombres son genericos para no acoplar el contrato
|
|
8
|
+
* al vocabulario del proveedor.
|
|
9
|
+
*/
|
|
10
|
+
export class SelectedProvider {
|
|
11
|
+
/** Plantilla del proveedor ya resuelta. Para Twilio se traduce a `contentSid` (HX...). */
|
|
12
|
+
@Expose() @IsString() @IsNotEmpty() templateId!: string;
|
|
13
|
+
|
|
14
|
+
/** Remitente ya resuelto. Para Twilio = Messaging Service SID (MG...) o numero `from`. */
|
|
15
|
+
@Expose() @IsString() @IsNotEmpty() senderId!: string;
|
|
16
|
+
|
|
17
|
+
/** Variables de la plantilla ya resueltas, keyeadas por slot posicional. Ej: { "1": "1234" }. */
|
|
18
|
+
@Expose() @IsOptional() @IsObject() contentVariables?: Record<string, string>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Referencia (nombre/ARN) al secret de Secrets Manager con las credenciales
|
|
22
|
+
* de la cuenta de Twilio de este `(tenant, channel)`. Ej: "twilio/FIADO/credentials".
|
|
23
|
+
* El connector resuelve el secret real con esta referencia justo antes de enviar.
|
|
24
|
+
* Opcional: si se omite, el connector usa su secret por defecto (TWILIO_SECRET_NAME).
|
|
25
|
+
*/
|
|
26
|
+
@Expose() @IsOptional() @IsString() secretRef?: string;
|
|
27
|
+
}
|