@fiado/type-kit 3.88.0 → 3.90.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 +3 -1
- package/bin/platformRbac/dtos/AuthContext.d.ts +6 -0
- package/bin/platformRbac/dtos/CreateUserFieldRequest.d.ts +10 -0
- package/bin/platformRbac/dtos/CreateUserFieldRequest.js +54 -0
- package/bin/platformRbac/dtos/InjectableUserAttributesResponse.d.ts +5 -0
- package/bin/platformRbac/dtos/InjectableUserAttributesResponse.js +2 -0
- package/bin/platformRbac/dtos/UpdateUserFieldRequest.d.ts +8 -0
- package/bin/platformRbac/dtos/UpdateUserFieldRequest.js +51 -0
- package/bin/platformRbac/dtos/UserFieldDef.d.ts +19 -0
- package/bin/platformRbac/dtos/UserFieldDef.js +2 -0
- package/bin/platformRbac/enums/Permission.d.ts +2 -0
- package/bin/platformRbac/enums/Permission.js +11 -0
- package/bin/platformRbac/enums/UserFieldType.d.ts +5 -0
- package/bin/platformRbac/enums/UserFieldType.js +9 -0
- package/bin/platformRbac/index.d.ts +5 -0
- package/bin/platformRbac/index.js +9 -1
- package/package.json +1 -1
- package/src/platformRbac/dtos/AuthContext.ts +6 -0
- package/src/platformRbac/dtos/CreateUserFieldRequest.ts +13 -0
- package/src/platformRbac/dtos/InjectableUserAttributesResponse.ts +5 -0
- package/src/platformRbac/dtos/UpdateUserFieldRequest.ts +11 -0
- package/src/platformRbac/dtos/UserFieldDef.ts +20 -0
- package/src/platformRbac/enums/Permission.ts +11 -0
- package/src/platformRbac/enums/UserFieldType.ts +5 -0
- package/src/platformRbac/index.ts +11 -0
|
@@ -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`] = `2374504554`;
|
|
4
4
|
|
|
5
5
|
exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe ante cualquier reorden/inserción) 1`] = `
|
|
6
6
|
[
|
|
@@ -120,5 +120,7 @@ exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe an
|
|
|
120
120
|
"agents.group.manage",
|
|
121
121
|
"agents.group.user.manage",
|
|
122
122
|
"agents.person.create",
|
|
123
|
+
"platform.tenant.userfields.manage",
|
|
124
|
+
"agents.app.access",
|
|
123
125
|
]
|
|
124
126
|
`;
|
|
@@ -24,4 +24,10 @@ export interface AuthContext {
|
|
|
24
24
|
permVer?: number;
|
|
25
25
|
/** @deprecated DEC-RBAC-008: epoch de permisos. El authorizer ya no lo chequea. */
|
|
26
26
|
permsEpoch?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Metadata de negocio por-usuario inyectada por jwt-inyector (campos personalizados del tenant
|
|
29
|
+
* marcados injectToToken). NO es autorización: NUNCA usar en un guard/decisión de acceso (DEC-RBAC-020).
|
|
30
|
+
* El gateway-adapter (buildAuthContextFromToken) parsea el claim JSON a este objeto.
|
|
31
|
+
*/
|
|
32
|
+
customAttributes?: Record<string, string>;
|
|
27
33
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { UserFieldType } from '../enums/UserFieldType';
|
|
2
|
+
/** Body del POST /backoffice/tenants/{tenantId}/user-fields. La validación de `options` por `type` (no vacío si select) la hace el manager. */
|
|
3
|
+
export declare class CreateUserFieldRequest {
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
type: UserFieldType;
|
|
7
|
+
options?: string[];
|
|
8
|
+
required: boolean;
|
|
9
|
+
injectToToken: boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
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.CreateUserFieldRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const UserFieldType_1 = require("../enums/UserFieldType");
|
|
16
|
+
/** Body del POST /backoffice/tenants/{tenantId}/user-fields. La validación de `options` por `type` (no vacío si select) la hace el manager. */
|
|
17
|
+
class CreateUserFieldRequest {
|
|
18
|
+
}
|
|
19
|
+
exports.CreateUserFieldRequest = CreateUserFieldRequest;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_transformer_1.Expose)(),
|
|
22
|
+
(0, class_validator_1.IsString)(),
|
|
23
|
+
(0, class_validator_1.Matches)(/^[a-z][a-zA-Z0-9_]*$/, { message: 'key debe ser slug ^[a-z][a-zA-Z0-9_]*$' }),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], CreateUserFieldRequest.prototype, "key", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, class_transformer_1.Expose)(),
|
|
28
|
+
(0, class_validator_1.IsString)(),
|
|
29
|
+
(0, class_validator_1.MaxLength)(80),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], CreateUserFieldRequest.prototype, "label", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, class_transformer_1.Expose)(),
|
|
34
|
+
(0, class_validator_1.IsEnum)(UserFieldType_1.UserFieldType),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], CreateUserFieldRequest.prototype, "type", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, class_transformer_1.Expose)(),
|
|
39
|
+
(0, class_validator_1.IsOptional)(),
|
|
40
|
+
(0, class_validator_1.IsArray)(),
|
|
41
|
+
(0, class_validator_1.ArrayNotEmpty)(),
|
|
42
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
43
|
+
__metadata("design:type", Array)
|
|
44
|
+
], CreateUserFieldRequest.prototype, "options", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, class_transformer_1.Expose)(),
|
|
47
|
+
(0, class_validator_1.IsBoolean)(),
|
|
48
|
+
__metadata("design:type", Boolean)
|
|
49
|
+
], CreateUserFieldRequest.prototype, "required", void 0);
|
|
50
|
+
__decorate([
|
|
51
|
+
(0, class_transformer_1.Expose)(),
|
|
52
|
+
(0, class_validator_1.IsBoolean)(),
|
|
53
|
+
__metadata("design:type", Boolean)
|
|
54
|
+
], CreateUserFieldRequest.prototype, "injectToToken", void 0);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Respuesta del GET /internal/users/{cognitoSub}/injectable-attributes (consumida por jwt-inyector). */
|
|
2
|
+
export interface InjectableUserAttributesResponse {
|
|
3
|
+
/** Solo los campos injectToToken && enabled del tenant que tengan valor en el usuario. */
|
|
4
|
+
customAttributes: Record<string, string>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Body del PATCH /backoffice/tenants/{tenantId}/user-fields/{key}. `key` y `type` NO son editables (inmutables, DEC-RBAC-016). */
|
|
2
|
+
export declare class UpdateUserFieldRequest {
|
|
3
|
+
label?: string;
|
|
4
|
+
options?: string[];
|
|
5
|
+
required?: boolean;
|
|
6
|
+
injectToToken?: boolean;
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
}
|
|
@@ -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.UpdateUserFieldRequest = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
/** Body del PATCH /backoffice/tenants/{tenantId}/user-fields/{key}. `key` y `type` NO son editables (inmutables, DEC-RBAC-016). */
|
|
16
|
+
class UpdateUserFieldRequest {
|
|
17
|
+
}
|
|
18
|
+
exports.UpdateUserFieldRequest = UpdateUserFieldRequest;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, class_transformer_1.Expose)(),
|
|
21
|
+
(0, class_validator_1.IsOptional)(),
|
|
22
|
+
(0, class_validator_1.IsString)(),
|
|
23
|
+
(0, class_validator_1.MaxLength)(80),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], UpdateUserFieldRequest.prototype, "label", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, class_transformer_1.Expose)(),
|
|
28
|
+
(0, class_validator_1.IsOptional)(),
|
|
29
|
+
(0, class_validator_1.IsArray)(),
|
|
30
|
+
(0, class_validator_1.ArrayNotEmpty)(),
|
|
31
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
32
|
+
__metadata("design:type", Array)
|
|
33
|
+
], UpdateUserFieldRequest.prototype, "options", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, class_transformer_1.Expose)(),
|
|
36
|
+
(0, class_validator_1.IsOptional)(),
|
|
37
|
+
(0, class_validator_1.IsBoolean)(),
|
|
38
|
+
__metadata("design:type", Boolean)
|
|
39
|
+
], UpdateUserFieldRequest.prototype, "required", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, class_transformer_1.Expose)(),
|
|
42
|
+
(0, class_validator_1.IsOptional)(),
|
|
43
|
+
(0, class_validator_1.IsBoolean)(),
|
|
44
|
+
__metadata("design:type", Boolean)
|
|
45
|
+
], UpdateUserFieldRequest.prototype, "injectToToken", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
(0, class_transformer_1.Expose)(),
|
|
48
|
+
(0, class_validator_1.IsOptional)(),
|
|
49
|
+
(0, class_validator_1.IsBoolean)(),
|
|
50
|
+
__metadata("design:type", Boolean)
|
|
51
|
+
], UpdateUserFieldRequest.prototype, "enabled", void 0);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { UserFieldType } from '../enums/UserFieldType';
|
|
2
|
+
/**
|
|
3
|
+
* Definición de un campo personalizado de usuario, embebida en PlatformTenantConfig.userFieldDefs.
|
|
4
|
+
* El `key` es inmutable (clave en el map de valores y en el claim). `enabled:false` = soft-disable.
|
|
5
|
+
* Timestamps inline: los setea el manager a mano (Dynamoose no mantiene sub-objetos inline). DEC-RBAC-016.
|
|
6
|
+
*/
|
|
7
|
+
export interface UserFieldDef {
|
|
8
|
+
key: string;
|
|
9
|
+
label: string;
|
|
10
|
+
type: UserFieldType;
|
|
11
|
+
options?: string[];
|
|
12
|
+
required: boolean;
|
|
13
|
+
injectToToken: boolean;
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
createdAt: number;
|
|
16
|
+
updatedAt: number;
|
|
17
|
+
createdBy: string;
|
|
18
|
+
updatedBy: string;
|
|
19
|
+
}
|
|
@@ -51,6 +51,7 @@ export declare enum Permission {
|
|
|
51
51
|
PLATFORM_ROLE_UPDATE = "platform.role.update",
|
|
52
52
|
PLATFORM_ROLE_DELETE = "platform.role.delete",
|
|
53
53
|
PLATFORM_AUDIT_VIEW = "platform.audit.view",
|
|
54
|
+
PLATFORM_TENANT_USERFIELDS_MANAGE = "platform.tenant.userfields.manage",
|
|
54
55
|
TENANT_USER_CREATE = "tenant.user.create",
|
|
55
56
|
TENANT_USER_CREATE_LATERAL = "tenant.user.create.lateral",
|
|
56
57
|
TENANT_USER_READ = "tenant.user.read",
|
|
@@ -119,6 +120,7 @@ export declare enum Permission {
|
|
|
119
120
|
MDM_OPERATION_LOG_VIEW = "mdm.operation_log.view",
|
|
120
121
|
MDM_TEST = "mdm.test",
|
|
121
122
|
PAY_TRANSACTION_VIEW = "pay.transaction.view",
|
|
123
|
+
AGENTS_APP_ACCESS = "agents.app.access",
|
|
122
124
|
AGENTS_AGENT_LIST = "agents.agent.list",
|
|
123
125
|
AGENTS_AGENT_CREATE = "agents.agent.create",
|
|
124
126
|
AGENTS_AGENT_CREATE_BULK = "agents.agent.create_bulk",
|
|
@@ -63,6 +63,7 @@ var Permission;
|
|
|
63
63
|
Permission["PLATFORM_ROLE_UPDATE"] = "platform.role.update";
|
|
64
64
|
Permission["PLATFORM_ROLE_DELETE"] = "platform.role.delete";
|
|
65
65
|
Permission["PLATFORM_AUDIT_VIEW"] = "platform.audit.view";
|
|
66
|
+
Permission["PLATFORM_TENANT_USERFIELDS_MANAGE"] = "platform.tenant.userfields.manage";
|
|
66
67
|
// ====================================================
|
|
67
68
|
// TENANT — operaciones dentro del silo de un tenant
|
|
68
69
|
// ====================================================
|
|
@@ -160,6 +161,9 @@ var Permission;
|
|
|
160
161
|
// (ver fiado-agents-webapp/docs/rbac/RBAC-agents.md §5.2). El aislamiento entre orgs lo da el
|
|
161
162
|
// scope GROUP del roleAssignment (scopeRef = Group_GT.id), no un permiso aparte.
|
|
162
163
|
// ====================================================
|
|
164
|
+
// Gate de ACCESO a la app web de Agents (gobernanza). Sin este permiso el usuario no
|
|
165
|
+
// entra a la app. Lo otorgan los 5 roles GROUP de agents (en su propio repo, no acá).
|
|
166
|
+
Permission["AGENTS_APP_ACCESS"] = "agents.app.access";
|
|
163
167
|
Permission["AGENTS_AGENT_LIST"] = "agents.agent.list";
|
|
164
168
|
Permission["AGENTS_AGENT_CREATE"] = "agents.agent.create";
|
|
165
169
|
Permission["AGENTS_AGENT_CREATE_BULK"] = "agents.agent.create_bulk";
|
|
@@ -321,6 +325,13 @@ exports.PERMISSION_BIT_ORDER = [
|
|
|
321
325
|
// Append-only: nuevo permiso agregado 2026-06-18 (DEC-A2-02). Va al FINAL para no correr los bits
|
|
322
326
|
// existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
|
|
323
327
|
Permission.AGENTS_PERSON_CREATE,
|
|
328
|
+
// Append-only 2026-06-18 (DEC-RBAC-017): catálogo de campos personalizados por tenant. Al FINAL para
|
|
329
|
+
// no correr bits existentes. (El bitset está deprecado por token-flaco, pero el orden se mantiene
|
|
330
|
+
// sincronizado con el enum para que el test de bits no rompa.)
|
|
331
|
+
Permission.PLATFORM_TENANT_USERFIELDS_MANAGE,
|
|
332
|
+
// Append-only 2026-06-21: gate de acceso a la app web de Agents (gobernanza). Al FINAL para no
|
|
333
|
+
// correr bits existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
|
|
334
|
+
Permission.AGENTS_APP_ACCESS,
|
|
324
335
|
];
|
|
325
336
|
function djb2(input) {
|
|
326
337
|
let h = 5381;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserFieldType = void 0;
|
|
4
|
+
/** Tipo de un campo personalizado de usuario. text = texto libre; select = lista cerrada de opciones. */
|
|
5
|
+
var UserFieldType;
|
|
6
|
+
(function (UserFieldType) {
|
|
7
|
+
UserFieldType["TEXT"] = "text";
|
|
8
|
+
UserFieldType["SELECT"] = "select";
|
|
9
|
+
})(UserFieldType || (exports.UserFieldType = UserFieldType = {}));
|
|
@@ -29,3 +29,8 @@ export type { CreateTenantResponse } from './dtos/CreateTenantResponse';
|
|
|
29
29
|
export * from './dtos/UpdateTenantSecurityPolicyRequest';
|
|
30
30
|
export type { TenantSecurityPolicyResponse } from './dtos/TenantSecurityPolicyResponse';
|
|
31
31
|
export { TenantType, TENANT_TYPES, levelsOf, tableSuffixForLevel, scopeRankOrder } from './tenantTypes';
|
|
32
|
+
export { UserFieldType } from './enums/UserFieldType';
|
|
33
|
+
export type { UserFieldDef } from './dtos/UserFieldDef';
|
|
34
|
+
export * from './dtos/CreateUserFieldRequest';
|
|
35
|
+
export * from './dtos/UpdateUserFieldRequest';
|
|
36
|
+
export type { InjectableUserAttributesResponse } from './dtos/InjectableUserAttributesResponse';
|
|
@@ -23,7 +23,7 @@ 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.bitsToPermissions = exports.permissionsToBits = exports.PERMS_VERSION = exports.PERMISSION_BIT_ORDER = exports.Permission = void 0;
|
|
26
|
+
exports.UserFieldType = 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
29
|
Object.defineProperty(exports, "PERMISSION_BIT_ORDER", { enumerable: true, get: function () { return Permission_1.PERMISSION_BIT_ORDER; } });
|
|
@@ -73,3 +73,11 @@ Object.defineProperty(exports, "TENANT_TYPES", { enumerable: true, get: function
|
|
|
73
73
|
Object.defineProperty(exports, "levelsOf", { enumerable: true, get: function () { return tenantTypes_1.levelsOf; } });
|
|
74
74
|
Object.defineProperty(exports, "tableSuffixForLevel", { enumerable: true, get: function () { return tenantTypes_1.tableSuffixForLevel; } });
|
|
75
75
|
Object.defineProperty(exports, "scopeRankOrder", { enumerable: true, get: function () { return tenantTypes_1.scopeRankOrder; } });
|
|
76
|
+
// Campos personalizados de usuario por tenant — embebidos en PlatformTenantConfig.userFieldDefs.
|
|
77
|
+
// UserFieldType es enum (export de valor); UserFieldDef es interface plain (type-only).
|
|
78
|
+
var UserFieldType_1 = require("./enums/UserFieldType");
|
|
79
|
+
Object.defineProperty(exports, "UserFieldType", { enumerable: true, get: function () { return UserFieldType_1.UserFieldType; } });
|
|
80
|
+
// DTOs de endpoints user-fields. Create/Update Request llevan decoradores class-validator → export de valor.
|
|
81
|
+
// InjectableUserAttributesResponse es interface plain (consumida por jwt-inyector) → type-only.
|
|
82
|
+
__exportStar(require("./dtos/CreateUserFieldRequest"), exports);
|
|
83
|
+
__exportStar(require("./dtos/UpdateUserFieldRequest"), exports);
|
package/package.json
CHANGED
|
@@ -25,4 +25,10 @@ export interface AuthContext {
|
|
|
25
25
|
permVer?: number;
|
|
26
26
|
/** @deprecated DEC-RBAC-008: epoch de permisos. El authorizer ya no lo chequea. */
|
|
27
27
|
permsEpoch?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Metadata de negocio por-usuario inyectada por jwt-inyector (campos personalizados del tenant
|
|
30
|
+
* marcados injectToToken). NO es autorización: NUNCA usar en un guard/decisión de acceso (DEC-RBAC-020).
|
|
31
|
+
* El gateway-adapter (buildAuthContextFromToken) parsea el claim JSON a este objeto.
|
|
32
|
+
*/
|
|
33
|
+
customAttributes?: Record<string, string>;
|
|
28
34
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { ArrayNotEmpty, IsArray, IsBoolean, IsEnum, IsOptional, IsString, Matches, MaxLength } from 'class-validator';
|
|
3
|
+
import { UserFieldType } from '../enums/UserFieldType';
|
|
4
|
+
|
|
5
|
+
/** Body del POST /backoffice/tenants/{tenantId}/user-fields. La validación de `options` por `type` (no vacío si select) la hace el manager. */
|
|
6
|
+
export class CreateUserFieldRequest {
|
|
7
|
+
@Expose() @IsString() @Matches(/^[a-z][a-zA-Z0-9_]*$/, { message: 'key debe ser slug ^[a-z][a-zA-Z0-9_]*$' }) key!: string;
|
|
8
|
+
@Expose() @IsString() @MaxLength(80) label!: string;
|
|
9
|
+
@Expose() @IsEnum(UserFieldType) type!: UserFieldType;
|
|
10
|
+
@Expose() @IsOptional() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) options?: string[];
|
|
11
|
+
@Expose() @IsBoolean() required!: boolean;
|
|
12
|
+
@Expose() @IsBoolean() injectToToken!: boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Respuesta del GET /internal/users/{cognitoSub}/injectable-attributes (consumida por jwt-inyector). */
|
|
2
|
+
export interface InjectableUserAttributesResponse {
|
|
3
|
+
/** Solo los campos injectToToken && enabled del tenant que tengan valor en el usuario. */
|
|
4
|
+
customAttributes: Record<string, string>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Expose } from 'class-transformer';
|
|
2
|
+
import { ArrayNotEmpty, IsArray, IsBoolean, IsOptional, IsString, MaxLength } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
/** Body del PATCH /backoffice/tenants/{tenantId}/user-fields/{key}. `key` y `type` NO son editables (inmutables, DEC-RBAC-016). */
|
|
5
|
+
export class UpdateUserFieldRequest {
|
|
6
|
+
@Expose() @IsOptional() @IsString() @MaxLength(80) label?: string;
|
|
7
|
+
@Expose() @IsOptional() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) options?: string[];
|
|
8
|
+
@Expose() @IsOptional() @IsBoolean() required?: boolean;
|
|
9
|
+
@Expose() @IsOptional() @IsBoolean() injectToToken?: boolean;
|
|
10
|
+
@Expose() @IsOptional() @IsBoolean() enabled?: boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { UserFieldType } from '../enums/UserFieldType';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Definición de un campo personalizado de usuario, embebida en PlatformTenantConfig.userFieldDefs.
|
|
5
|
+
* El `key` es inmutable (clave en el map de valores y en el claim). `enabled:false` = soft-disable.
|
|
6
|
+
* Timestamps inline: los setea el manager a mano (Dynamoose no mantiene sub-objetos inline). DEC-RBAC-016.
|
|
7
|
+
*/
|
|
8
|
+
export interface UserFieldDef {
|
|
9
|
+
key: string;
|
|
10
|
+
label: string;
|
|
11
|
+
type: UserFieldType;
|
|
12
|
+
options?: string[];
|
|
13
|
+
required: boolean;
|
|
14
|
+
injectToToken: boolean;
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
createdAt: number;
|
|
17
|
+
updatedAt: number;
|
|
18
|
+
createdBy: string;
|
|
19
|
+
updatedBy: string;
|
|
20
|
+
}
|
|
@@ -58,6 +58,7 @@ export enum Permission {
|
|
|
58
58
|
PLATFORM_ROLE_UPDATE = 'platform.role.update',
|
|
59
59
|
PLATFORM_ROLE_DELETE = 'platform.role.delete',
|
|
60
60
|
PLATFORM_AUDIT_VIEW = 'platform.audit.view',
|
|
61
|
+
PLATFORM_TENANT_USERFIELDS_MANAGE = 'platform.tenant.userfields.manage',
|
|
61
62
|
|
|
62
63
|
// ====================================================
|
|
63
64
|
// TENANT — operaciones dentro del silo de un tenant
|
|
@@ -161,6 +162,9 @@ export enum Permission {
|
|
|
161
162
|
// (ver fiado-agents-webapp/docs/rbac/RBAC-agents.md §5.2). El aislamiento entre orgs lo da el
|
|
162
163
|
// scope GROUP del roleAssignment (scopeRef = Group_GT.id), no un permiso aparte.
|
|
163
164
|
// ====================================================
|
|
165
|
+
// Gate de ACCESO a la app web de Agents (gobernanza). Sin este permiso el usuario no
|
|
166
|
+
// entra a la app. Lo otorgan los 5 roles GROUP de agents (en su propio repo, no acá).
|
|
167
|
+
AGENTS_APP_ACCESS = 'agents.app.access',
|
|
164
168
|
AGENTS_AGENT_LIST = 'agents.agent.list',
|
|
165
169
|
AGENTS_AGENT_CREATE = 'agents.agent.create',
|
|
166
170
|
AGENTS_AGENT_CREATE_BULK = 'agents.agent.create_bulk',
|
|
@@ -323,6 +327,13 @@ export const PERMISSION_BIT_ORDER: readonly Permission[] = [
|
|
|
323
327
|
// Append-only: nuevo permiso agregado 2026-06-18 (DEC-A2-02). Va al FINAL para no correr los bits
|
|
324
328
|
// existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
|
|
325
329
|
Permission.AGENTS_PERSON_CREATE,
|
|
330
|
+
// Append-only 2026-06-18 (DEC-RBAC-017): catálogo de campos personalizados por tenant. Al FINAL para
|
|
331
|
+
// no correr bits existentes. (El bitset está deprecado por token-flaco, pero el orden se mantiene
|
|
332
|
+
// sincronizado con el enum para que el test de bits no rompa.)
|
|
333
|
+
Permission.PLATFORM_TENANT_USERFIELDS_MANAGE,
|
|
334
|
+
// Append-only 2026-06-21: gate de acceso a la app web de Agents (gobernanza). Al FINAL para no
|
|
335
|
+
// correr bits existentes (PERMS_VERSION cambia, pero los índices previos se conservan).
|
|
336
|
+
Permission.AGENTS_APP_ACCESS,
|
|
326
337
|
] as const;
|
|
327
338
|
|
|
328
339
|
function djb2(input: string): number {
|
|
@@ -62,3 +62,14 @@ export type { TenantSecurityPolicyResponse } from './dtos/TenantSecurityPolicyRe
|
|
|
62
62
|
// Consumido por ScopeValidationService._rank vía scopeRankOrder() y por los seeds.
|
|
63
63
|
// Accesible bajo el namespace PlatformRbac (el index raíz hace export * as PlatformRbac).
|
|
64
64
|
export { TenantType, TENANT_TYPES, levelsOf, tableSuffixForLevel, scopeRankOrder } from './tenantTypes';
|
|
65
|
+
|
|
66
|
+
// Campos personalizados de usuario por tenant — embebidos en PlatformTenantConfig.userFieldDefs.
|
|
67
|
+
// UserFieldType es enum (export de valor); UserFieldDef es interface plain (type-only).
|
|
68
|
+
export { UserFieldType } from './enums/UserFieldType';
|
|
69
|
+
export type { UserFieldDef } from './dtos/UserFieldDef';
|
|
70
|
+
|
|
71
|
+
// DTOs de endpoints user-fields. Create/Update Request llevan decoradores class-validator → export de valor.
|
|
72
|
+
// InjectableUserAttributesResponse es interface plain (consumida por jwt-inyector) → type-only.
|
|
73
|
+
export * from './dtos/CreateUserFieldRequest';
|
|
74
|
+
export * from './dtos/UpdateUserFieldRequest';
|
|
75
|
+
export type { InjectableUserAttributesResponse } from './dtos/InjectableUserAttributesResponse';
|