@fiado/type-kit 3.487.0 → 3.488.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.
Files changed (55) hide show
  1. package/_test_/unit/cognitoBackofficeConnector/dtos/CreatePoolClientRequest.test.ts +55 -0
  2. package/_test_/unit/cognitoBackofficeConnector/dtos/CreateUserRequest.primaryVerified.test.ts +23 -0
  3. package/_test_/unit/platformRbac/apiUser/apiUserDtos.test.ts +56 -0
  4. package/_test_/unit/platformRbac/enums/AccountType.test.ts +11 -0
  5. package/_test_/unit/platformRbac/enums/__snapshots__/permissionBits.test.ts.snap +2 -1
  6. package/_test_/unit/platformRbac/enums/apiUserPermission.test.ts +11 -0
  7. package/bin/cognitoBackofficeConnector/dtos/AppClientConfig.d.ts +8 -7
  8. package/bin/cognitoBackofficeConnector/dtos/AppClientConfig.js +23 -10
  9. package/bin/cognitoBackofficeConnector/dtos/CreatePoolClientRequest.d.ts +6 -0
  10. package/bin/cognitoBackofficeConnector/dtos/CreatePoolClientRequest.js +31 -0
  11. package/bin/cognitoBackofficeConnector/dtos/CreatePoolClientResponse.d.ts +4 -0
  12. package/bin/cognitoBackofficeConnector/dtos/CreatePoolClientResponse.js +7 -0
  13. package/bin/cognitoBackofficeConnector/dtos/CreateUserRequest.d.ts +2 -0
  14. package/bin/cognitoBackofficeConnector/dtos/CreateUserRequest.js +6 -0
  15. package/bin/cognitoBackofficeConnector/index.d.ts +2 -0
  16. package/bin/cognitoBackofficeConnector/index.js +2 -0
  17. package/bin/platformRbac/apiUser/ApiLoginRequest.d.ts +6 -0
  18. package/bin/platformRbac/apiUser/ApiLoginRequest.js +36 -0
  19. package/bin/platformRbac/apiUser/ApiLoginResponse.d.ts +6 -0
  20. package/bin/platformRbac/apiUser/ApiLoginResponse.js +7 -0
  21. package/bin/platformRbac/apiUser/ApiUserWhoamiResponse.d.ts +7 -0
  22. package/bin/platformRbac/apiUser/ApiUserWhoamiResponse.js +7 -0
  23. package/bin/platformRbac/apiUser/CreateApiUserRequest.d.ts +8 -0
  24. package/bin/platformRbac/apiUser/CreateApiUserRequest.js +45 -0
  25. package/bin/platformRbac/apiUser/CreateApiUserResponse.d.ts +9 -0
  26. package/bin/platformRbac/apiUser/CreateApiUserResponse.js +7 -0
  27. package/bin/platformRbac/apiUser/RotateApiUserSecretResponse.d.ts +5 -0
  28. package/bin/platformRbac/apiUser/RotateApiUserSecretResponse.js +7 -0
  29. package/bin/platformRbac/apiUser/UpdateApiUserAccessRequest.d.ts +5 -0
  30. package/bin/platformRbac/apiUser/UpdateApiUserAccessRequest.js +33 -0
  31. package/bin/platformRbac/enums/AccountType.d.ts +5 -0
  32. package/bin/platformRbac/enums/AccountType.js +9 -0
  33. package/bin/platformRbac/enums/Permission.d.ts +2 -1
  34. package/bin/platformRbac/enums/Permission.js +3 -0
  35. package/bin/platformRbac/enums/PrincipalKind.d.ts +3 -1
  36. package/bin/platformRbac/enums/PrincipalKind.js +2 -0
  37. package/bin/platformRbac/index.d.ts +8 -0
  38. package/bin/platformRbac/index.js +11 -1
  39. package/package.json +1 -1
  40. package/src/cognitoBackofficeConnector/dtos/AppClientConfig.ts +20 -10
  41. package/src/cognitoBackofficeConnector/dtos/CreatePoolClientRequest.ts +9 -0
  42. package/src/cognitoBackofficeConnector/dtos/CreatePoolClientResponse.ts +4 -0
  43. package/src/cognitoBackofficeConnector/dtos/CreateUserRequest.ts +2 -0
  44. package/src/cognitoBackofficeConnector/index.ts +2 -0
  45. package/src/platformRbac/apiUser/ApiLoginRequest.ts +9 -0
  46. package/src/platformRbac/apiUser/ApiLoginResponse.ts +6 -0
  47. package/src/platformRbac/apiUser/ApiUserWhoamiResponse.ts +7 -0
  48. package/src/platformRbac/apiUser/CreateApiUserRequest.ts +11 -0
  49. package/src/platformRbac/apiUser/CreateApiUserResponse.ts +10 -0
  50. package/src/platformRbac/apiUser/RotateApiUserSecretResponse.ts +5 -0
  51. package/src/platformRbac/apiUser/UpdateApiUserAccessRequest.ts +8 -0
  52. package/src/platformRbac/enums/AccountType.ts +5 -0
  53. package/src/platformRbac/enums/Permission.ts +3 -0
  54. package/src/platformRbac/enums/PrincipalKind.ts +2 -0
  55. package/src/platformRbac/index.ts +10 -0
@@ -0,0 +1,55 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { CreatePoolClientRequest } from '../../../../src/cognitoBackofficeConnector/dtos/CreatePoolClientRequest';
5
+ import { AppClientConfig } from '../../../../src/cognitoBackofficeConnector/dtos/AppClientConfig';
6
+
7
+ const CLIENT = {
8
+ clientName: 'us-east-1_abc-api-client',
9
+ explicitAuthFlows: ['ALLOW_ADMIN_USER_PASSWORD_AUTH'],
10
+ tokenValidityUnits: 'minutes',
11
+ accessTokenValidity: 15,
12
+ idTokenValidity: 15,
13
+ refreshTokenValidity: 60,
14
+ preventUserExistenceErrors: true,
15
+ enableTokenRevocation: true,
16
+ writeAttributes: ['name'],
17
+ };
18
+
19
+ describe('CreatePoolClientRequest (reutiliza AppClientConfig)', () => {
20
+ it('acepta el client de API completo', async () => {
21
+ expect(await validate(plainToInstance(CreatePoolClientRequest, { region: 'us-east-1', appClientConfig: CLIENT }))).toEqual([]);
22
+ });
23
+
24
+ it('exige region', async () => {
25
+ const errors = await validate(plainToInstance(CreatePoolClientRequest, { region: '', appClientConfig: CLIENT }));
26
+ expect(errors.some((e) => e.property === 'region')).toBe(true);
27
+ });
28
+
29
+ it('valida el AppClientConfig anidado', async () => {
30
+ const errors = await validate(plainToInstance(CreatePoolClientRequest, { region: 'us-east-1', appClientConfig: { ...CLIENT, explicitAuthFlows: ['ALLOW_INVENTADO'] } }));
31
+ expect(errors.some((e) => e.property === 'appClientConfig')).toBe(true);
32
+ });
33
+ });
34
+
35
+ describe('AppClientConfig endurecido', () => {
36
+ it('acepta los flujos que usa el onboarding', async () => {
37
+ const dto = plainToInstance(AppClientConfig, { explicitAuthFlows: ['ALLOW_ADMIN_USER_PASSWORD_AUTH', 'ALLOW_CUSTOM_AUTH', 'ALLOW_REFRESH_TOKEN_AUTH'], refreshTokenValidity: 30 });
38
+ expect(await validate(dto)).toEqual([]);
39
+ });
40
+
41
+ it('rechaza un flujo desconocido', async () => {
42
+ const errors = await validate(plainToInstance(AppClientConfig, { explicitAuthFlows: ['ALLOW_INVENTADO'] }));
43
+ expect(errors.some((e) => e.property === 'explicitAuthFlows')).toBe(true);
44
+ });
45
+
46
+ it('rechaza una unidad de vigencia desconocida', async () => {
47
+ const errors = await validate(plainToInstance(AppClientConfig, { explicitAuthFlows: ['ALLOW_ADMIN_USER_PASSWORD_AUTH'], tokenValidityUnits: 'weeks' }));
48
+ expect(errors.some((e) => e.property === 'tokenValidityUnits')).toBe(true);
49
+ });
50
+
51
+ it('acepta writeAttributes', async () => {
52
+ const errors = await validate(plainToInstance(AppClientConfig, { explicitAuthFlows: ['ALLOW_ADMIN_USER_PASSWORD_AUTH'], writeAttributes: ['name'] }));
53
+ expect(errors).toEqual([]);
54
+ });
55
+ });
@@ -0,0 +1,23 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { CreateUserRequest } from '../../../../src/cognitoBackofficeConnector/dtos/CreateUserRequest';
5
+
6
+ describe('CreateUserRequest.primaryIdentifierVerified', () => {
7
+ const base = { userPoolId: 'us-east-1_p', region: 'us-east-1', email: 'api-1@api.surekeep.invalid', tenantId: 'surekeep' };
8
+
9
+ it('es opcional', async () => {
10
+ expect(await validate(plainToInstance(CreateUserRequest, base))).toEqual([]);
11
+ });
12
+
13
+ it('acepta false', async () => {
14
+ const dto = plainToInstance(CreateUserRequest, { ...base, primaryIdentifierVerified: false });
15
+ expect(await validate(dto)).toEqual([]);
16
+ expect(dto.primaryIdentifierVerified).toBe(false);
17
+ });
18
+
19
+ it('rechaza un valor no booleano', async () => {
20
+ const errors = await validate(plainToInstance(CreateUserRequest, { ...base, primaryIdentifierVerified: 'no' }));
21
+ expect(errors.some((e) => e.property === 'primaryIdentifierVerified')).toBe(true);
22
+ });
23
+ });
@@ -0,0 +1,56 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import {
5
+ AccountType,
6
+ ApiLoginRequest,
7
+ CreateApiUserRequest,
8
+ UpdateApiUserAccessRequest,
9
+ } from '../../../../src/platformRbac';
10
+
11
+ describe('ApiLoginRequest', () => {
12
+ const valid = { clientId: '0b9f1c2e-1111-4222-8333-444455556666', clientSecret: 's3cr3t', tenantId: 'surekeep' };
13
+
14
+ it('acepta el body completo', async () => {
15
+ expect(await validate(plainToInstance(ApiLoginRequest, valid))).toEqual([]);
16
+ });
17
+
18
+ it.each(['clientId', 'clientSecret', 'tenantId'])('exige %s', async (field) => {
19
+ const errors = await validate(plainToInstance(ApiLoginRequest, { ...valid, [field]: '' }));
20
+ expect(errors.some((e) => e.property === field)).toBe(true);
21
+ });
22
+ });
23
+
24
+ describe('CreateApiUserRequest', () => {
25
+ const valid = { accountType: AccountType.API, displayName: 'La Central', technicalContact: 'ops@central.mx', ipAllowlist: ['189.128.0.0/16'] };
26
+
27
+ it('acepta el alta completa', async () => {
28
+ expect(await validate(plainToInstance(CreateApiUserRequest, valid))).toEqual([]);
29
+ });
30
+
31
+ it('exige accountType API', async () => {
32
+ const errors = await validate(plainToInstance(CreateApiUserRequest, { ...valid, accountType: 'HUMAN' }));
33
+ expect(errors.some((e) => e.property === 'accountType')).toBe(true);
34
+ });
35
+
36
+ it('exige displayName', async () => {
37
+ const errors = await validate(plainToInstance(CreateApiUserRequest, { ...valid, displayName: '' }));
38
+ expect(errors.some((e) => e.property === 'displayName')).toBe(true);
39
+ });
40
+
41
+ it('exige una lista de IPs no vacía', async () => {
42
+ const errors = await validate(plainToInstance(CreateApiUserRequest, { ...valid, ipAllowlist: [] }));
43
+ expect(errors.some((e) => e.property === 'ipAllowlist')).toBe(true);
44
+ });
45
+ });
46
+
47
+ describe('UpdateApiUserAccessRequest', () => {
48
+ it('acepta solo IPs', async () => {
49
+ expect(await validate(plainToInstance(UpdateApiUserAccessRequest, { ipAllowlist: ['10.0.0.0/8'] }))).toEqual([]);
50
+ });
51
+
52
+ it('rechaza una lista vacía', async () => {
53
+ const errors = await validate(plainToInstance(UpdateApiUserAccessRequest, { ipAllowlist: [] }));
54
+ expect(errors.some((e) => e.property === 'ipAllowlist')).toBe(true);
55
+ });
56
+ });
@@ -0,0 +1,11 @@
1
+ import { AccountType, PrincipalKind } from '../../../../src/platformRbac';
2
+
3
+ describe('AccountType y PrincipalKind (usuarios de API)', () => {
4
+ it('AccountType tiene exactamente HUMAN y API', () => {
5
+ expect(Object.values(AccountType)).toEqual(['HUMAN', 'API']);
6
+ });
7
+
8
+ it('PrincipalKind suma API_USER al final sin tocar los existentes', () => {
9
+ expect(Object.values(PrincipalKind)).toEqual(['USER', 'INTEGRATION', 'API_USER']);
10
+ });
11
+ });
@@ -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`] = `3833769424`;
3
+ exports[`PERMISSION_BIT_ORDER PERMS_VERSION es número estable 1`] = `2686516275`;
4
4
 
5
5
  exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe ante cualquier reorden/inserción) 1`] = `
6
6
  [
@@ -95,5 +95,6 @@ exports[`PERMISSION_BIT_ORDER append-only: snapshot del ORDEN COMPLETO (rompe an
95
95
  "platform.integration.key.issue",
96
96
  "platform.integration.key.revoke",
97
97
  "tenant.integration.diagnostic",
98
+ "tenant.api_user.manage",
98
99
  ]
99
100
  `;
@@ -0,0 +1,11 @@
1
+ import { Permission, PERMISSION_BIT_ORDER } from '../../../../src/platformRbac/enums/Permission';
2
+
3
+ describe('Permiso de administración de usuarios de API', () => {
4
+ it('existe con la llave tenant.api_user.manage', () => {
5
+ expect(Permission.TENANT_API_USER_MANAGE).toBe('tenant.api_user.manage');
6
+ });
7
+
8
+ it('va al FINAL del orden de bits (append-only)', () => {
9
+ expect(PERMISSION_BIT_ORDER[PERMISSION_BIT_ORDER.length - 1]).toBe(Permission.TENANT_API_USER_MANAGE);
10
+ });
11
+ });
@@ -1,11 +1,10 @@
1
+ /** Flujos de autenticación que Cognito admite en un app client. */
2
+ export declare const COGNITO_EXPLICIT_AUTH_FLOWS: readonly string[];
3
+ /** Unidades de vigencia de token; el conector aplica una sola a los tres tokens. */
4
+ export declare const COGNITO_TOKEN_VALIDITY_UNITS: readonly string[];
1
5
  /**
2
- * Config del único App Client del pool nuevo creado por POST /pools.
3
- *
4
- * NO expone `generateSecret` — el connector hardcodea `GenerateSecret: false`
5
- * en el SDK call (BFF pattern: rbac llama al connector server-to-server vía
6
- * api-invoker en VPC, sin SPA-to-Cognito directo que requiera client secret).
7
- * Decisión arquitectónica A21 del connector. Si aparece consumer B2B/M2M con
8
- * flow `client_credentials`, evaluar con líder + bump major del connector.
6
+ * Config de un app client (el del pool nuevo de POST /pools o uno extra de POST /pools/{id}/clients).
7
+ * Sin `generateSecret`: el conector fija GenerateSecret false (A21).
9
8
  */
10
9
  export declare class AppClientConfig {
11
10
  clientName?: string;
@@ -16,4 +15,6 @@ export declare class AppClientConfig {
16
15
  refreshTokenValidity?: number;
17
16
  preventUserExistenceErrors?: boolean;
18
17
  enableTokenRevocation?: boolean;
18
+ /** Atributos que el usuario puede escribir con su propio token. Ausente ⇒ todos (default de Cognito). */
19
+ writeAttributes?: string[];
19
20
  }
@@ -9,17 +9,23 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.AppClientConfig = void 0;
12
+ exports.AppClientConfig = exports.COGNITO_TOKEN_VALIDITY_UNITS = exports.COGNITO_EXPLICIT_AUTH_FLOWS = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
+ /** Flujos de autenticación que Cognito admite en un app client. */
16
+ exports.COGNITO_EXPLICIT_AUTH_FLOWS = [
17
+ 'ALLOW_ADMIN_USER_PASSWORD_AUTH',
18
+ 'ALLOW_CUSTOM_AUTH',
19
+ 'ALLOW_USER_PASSWORD_AUTH',
20
+ 'ALLOW_USER_SRP_AUTH',
21
+ 'ALLOW_REFRESH_TOKEN_AUTH',
22
+ 'ALLOW_USER_AUTH',
23
+ ];
24
+ /** Unidades de vigencia de token; el conector aplica una sola a los tres tokens. */
25
+ exports.COGNITO_TOKEN_VALIDITY_UNITS = ['seconds', 'minutes', 'hours', 'days'];
15
26
  /**
16
- * Config del único App Client del pool nuevo creado por POST /pools.
17
- *
18
- * NO expone `generateSecret` — el connector hardcodea `GenerateSecret: false`
19
- * en el SDK call (BFF pattern: rbac llama al connector server-to-server vía
20
- * api-invoker en VPC, sin SPA-to-Cognito directo que requiera client secret).
21
- * Decisión arquitectónica A21 del connector. Si aparece consumer B2B/M2M con
22
- * flow `client_credentials`, evaluar con líder + bump major del connector.
27
+ * Config de un app client (el del pool nuevo de POST /pools o uno extra de POST /pools/{id}/clients).
28
+ * Sin `generateSecret`: el conector fija GenerateSecret false (A21).
23
29
  */
24
30
  class AppClientConfig {
25
31
  }
@@ -33,13 +39,13 @@ __decorate([
33
39
  __decorate([
34
40
  (0, class_transformer_1.Expose)(),
35
41
  (0, class_validator_1.IsArray)(),
36
- (0, class_validator_1.IsString)({ each: true }),
42
+ (0, class_validator_1.IsIn)(exports.COGNITO_EXPLICIT_AUTH_FLOWS, { each: true }),
37
43
  __metadata("design:type", Array)
38
44
  ], AppClientConfig.prototype, "explicitAuthFlows", void 0);
39
45
  __decorate([
40
46
  (0, class_transformer_1.Expose)(),
41
47
  (0, class_validator_1.IsOptional)(),
42
- (0, class_validator_1.IsString)(),
48
+ (0, class_validator_1.IsIn)(exports.COGNITO_TOKEN_VALIDITY_UNITS),
43
49
  __metadata("design:type", String)
44
50
  ], AppClientConfig.prototype, "tokenValidityUnits", void 0);
45
51
  __decorate([
@@ -72,3 +78,10 @@ __decorate([
72
78
  (0, class_validator_1.IsBoolean)(),
73
79
  __metadata("design:type", Boolean)
74
80
  ], AppClientConfig.prototype, "enableTokenRevocation", void 0);
81
+ __decorate([
82
+ (0, class_transformer_1.Expose)(),
83
+ (0, class_validator_1.IsOptional)(),
84
+ (0, class_validator_1.IsArray)(),
85
+ (0, class_validator_1.IsString)({ each: true }),
86
+ __metadata("design:type", Array)
87
+ ], AppClientConfig.prototype, "writeAttributes", void 0);
@@ -0,0 +1,6 @@
1
+ import { AppClientConfig } from './AppClientConfig';
2
+ /** Body de POST /pools/{userPoolId}/clients: un app client extra sobre un pool existente. */
3
+ export declare class CreatePoolClientRequest {
4
+ region: string;
5
+ appClientConfig: AppClientConfig;
6
+ }
@@ -0,0 +1,31 @@
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.CreatePoolClientRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const AppClientConfig_1 = require("./AppClientConfig");
16
+ /** Body de POST /pools/{userPoolId}/clients: un app client extra sobre un pool existente. */
17
+ class CreatePoolClientRequest {
18
+ }
19
+ exports.CreatePoolClientRequest = CreatePoolClientRequest;
20
+ __decorate([
21
+ (0, class_transformer_1.Expose)(),
22
+ (0, class_validator_1.IsString)(),
23
+ (0, class_validator_1.IsNotEmpty)(),
24
+ __metadata("design:type", String)
25
+ ], CreatePoolClientRequest.prototype, "region", void 0);
26
+ __decorate([
27
+ (0, class_transformer_1.Expose)(),
28
+ (0, class_validator_1.ValidateNested)(),
29
+ (0, class_transformer_1.Type)(() => AppClientConfig_1.AppClientConfig),
30
+ __metadata("design:type", AppClientConfig_1.AppClientConfig)
31
+ ], CreatePoolClientRequest.prototype, "appClientConfig", void 0);
@@ -0,0 +1,4 @@
1
+ /** Respuesta de POST /pools/{userPoolId}/clients. Sin secret: el client nace con GenerateSecret false. */
2
+ export declare class CreatePoolClientResponse {
3
+ appClientId: string;
4
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreatePoolClientResponse = void 0;
4
+ /** Respuesta de POST /pools/{userPoolId}/clients. Sin secret: el client nace con GenerateSecret false. */
5
+ class CreatePoolClientResponse {
6
+ }
7
+ exports.CreatePoolClientResponse = CreatePoolClientResponse;
@@ -10,4 +10,6 @@ export declare class CreateUserRequest {
10
10
  tenantId: string;
11
11
  temporaryPassword?: string;
12
12
  suppressInvitationEmail?: boolean;
13
+ /** Ausente ⇒ true. false crea el identificador primario sin verificar (usuario de API). */
14
+ primaryIdentifierVerified?: boolean;
13
15
  }
@@ -69,3 +69,9 @@ __decorate([
69
69
  (0, class_validator_1.IsBoolean)(),
70
70
  __metadata("design:type", Boolean)
71
71
  ], CreateUserRequest.prototype, "suppressInvitationEmail", void 0);
72
+ __decorate([
73
+ (0, class_transformer_1.Expose)(),
74
+ (0, class_validator_1.IsOptional)(),
75
+ (0, class_validator_1.IsBoolean)(),
76
+ __metadata("design:type", Boolean)
77
+ ], CreateUserRequest.prototype, "primaryIdentifierVerified", void 0);
@@ -49,6 +49,8 @@ export * from './dtos/AppClientConfig';
49
49
  export * from './dtos/CreatePoolRequest';
50
50
  export * from './dtos/CreatePoolResponse';
51
51
  export * from './dtos/DeletePoolRequest';
52
+ export * from './dtos/CreatePoolClientRequest';
53
+ export * from './dtos/CreatePoolClientResponse';
52
54
  export * from './enums/IntrospectFailReason';
53
55
  export * from './dtos/IntrospectRequest';
54
56
  export * from './dtos/IntrospectResponse';
@@ -65,6 +65,8 @@ __exportStar(require("./dtos/AppClientConfig"), exports);
65
65
  __exportStar(require("./dtos/CreatePoolRequest"), exports);
66
66
  __exportStar(require("./dtos/CreatePoolResponse"), exports);
67
67
  __exportStar(require("./dtos/DeletePoolRequest"), exports);
68
+ __exportStar(require("./dtos/CreatePoolClientRequest"), exports);
69
+ __exportStar(require("./dtos/CreatePoolClientResponse"), exports);
68
70
  // Introspección de token (POST /auth/introspect) — consumido por el platform-rbac-business.
69
71
  __exportStar(require("./enums/IntrospectFailReason"), exports);
70
72
  __exportStar(require("./dtos/IntrospectRequest"), exports);
@@ -0,0 +1,6 @@
1
+ /** Body de POST /auth/api/login. clientId es el sub del usuario de API y clientSecret su secreto. */
2
+ export declare class ApiLoginRequest {
3
+ clientId: string;
4
+ clientSecret: string;
5
+ tenantId: string;
6
+ }
@@ -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.ApiLoginRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /** Body de POST /auth/api/login. clientId es el sub del usuario de API y clientSecret su secreto. */
16
+ class ApiLoginRequest {
17
+ }
18
+ exports.ApiLoginRequest = ApiLoginRequest;
19
+ __decorate([
20
+ (0, class_transformer_1.Expose)(),
21
+ (0, class_validator_1.IsString)(),
22
+ (0, class_validator_1.IsNotEmpty)(),
23
+ __metadata("design:type", String)
24
+ ], ApiLoginRequest.prototype, "clientId", void 0);
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
+ ], ApiLoginRequest.prototype, "clientSecret", 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
+ ], ApiLoginRequest.prototype, "tenantId", void 0);
@@ -0,0 +1,6 @@
1
+ /** Respuesta 200 del login de API: solo el access token, nunca el refresh. */
2
+ export declare class ApiLoginResponse {
3
+ accessToken: string;
4
+ expiresIn: number;
5
+ tokenType: 'Bearer';
6
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiLoginResponse = void 0;
4
+ /** Respuesta 200 del login de API: solo el access token, nunca el refresh. */
5
+ class ApiLoginResponse {
6
+ }
7
+ exports.ApiLoginResponse = ApiLoginResponse;
@@ -0,0 +1,7 @@
1
+ /** Diagnóstico del W5 para usuarios de API: el principal ya resuelto por el adapter. */
2
+ export declare class ApiUserWhoamiResponse {
3
+ principalType: 'API_USER';
4
+ principalId: string;
5
+ tenantId: string;
6
+ permissions: string[];
7
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiUserWhoamiResponse = void 0;
4
+ /** Diagnóstico del W5 para usuarios de API: el principal ya resuelto por el adapter. */
5
+ class ApiUserWhoamiResponse {
6
+ }
7
+ exports.ApiUserWhoamiResponse = ApiUserWhoamiResponse;
@@ -0,0 +1,8 @@
1
+ import { AccountType } from '../enums/AccountType';
2
+ /** Alta de un usuario de API por POST /tenants/{tenantId}/users con accountType API. */
3
+ export declare class CreateApiUserRequest {
4
+ accountType: AccountType;
5
+ displayName: string;
6
+ technicalContact?: string;
7
+ ipAllowlist: string[];
8
+ }
@@ -0,0 +1,45 @@
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.CreateApiUserRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const AccountType_1 = require("../enums/AccountType");
16
+ /** Alta de un usuario de API por POST /tenants/{tenantId}/users con accountType API. */
17
+ class CreateApiUserRequest {
18
+ }
19
+ exports.CreateApiUserRequest = CreateApiUserRequest;
20
+ __decorate([
21
+ (0, class_transformer_1.Expose)(),
22
+ (0, class_validator_1.IsIn)([AccountType_1.AccountType.API]),
23
+ __metadata("design:type", String)
24
+ ], CreateApiUserRequest.prototype, "accountType", void 0);
25
+ __decorate([
26
+ (0, class_transformer_1.Expose)(),
27
+ (0, class_validator_1.IsString)(),
28
+ (0, class_validator_1.IsNotEmpty)(),
29
+ (0, class_validator_1.MaxLength)(120),
30
+ __metadata("design:type", String)
31
+ ], CreateApiUserRequest.prototype, "displayName", void 0);
32
+ __decorate([
33
+ (0, class_transformer_1.Expose)(),
34
+ (0, class_validator_1.IsOptional)(),
35
+ (0, class_validator_1.IsString)(),
36
+ (0, class_validator_1.MaxLength)(200),
37
+ __metadata("design:type", String)
38
+ ], CreateApiUserRequest.prototype, "technicalContact", void 0);
39
+ __decorate([
40
+ (0, class_transformer_1.Expose)(),
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
+ ], CreateApiUserRequest.prototype, "ipAllowlist", void 0);
@@ -0,0 +1,9 @@
1
+ import type { AccountType } from '../enums/AccountType';
2
+ /** Credenciales del usuario de API recién creado. El secreto sale UNA sola vez. */
3
+ export declare class CreateApiUserResponse {
4
+ cognitoSub: string;
5
+ clientId: string;
6
+ clientSecret: string;
7
+ status: 'ACTIVE';
8
+ accountType: AccountType;
9
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateApiUserResponse = void 0;
4
+ /** Credenciales del usuario de API recién creado. El secreto sale UNA sola vez. */
5
+ class CreateApiUserResponse {
6
+ }
7
+ exports.CreateApiUserResponse = CreateApiUserResponse;
@@ -0,0 +1,5 @@
1
+ /** Secreto nuevo tras rotar. El anterior y los tokens vivos dejan de servir. */
2
+ export declare class RotateApiUserSecretResponse {
3
+ clientId: string;
4
+ clientSecret: string;
5
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RotateApiUserSecretResponse = void 0;
4
+ /** Secreto nuevo tras rotar. El anterior y los tokens vivos dejan de servir. */
5
+ class RotateApiUserSecretResponse {
6
+ }
7
+ exports.RotateApiUserSecretResponse = RotateApiUserSecretResponse;
@@ -0,0 +1,5 @@
1
+ /** Body de PUT /tenants/{tenantId}/users/{cognitoSub}/api-access. */
2
+ export declare class UpdateApiUserAccessRequest {
3
+ ipAllowlist?: string[];
4
+ technicalContact?: string;
5
+ }
@@ -0,0 +1,33 @@
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.UpdateApiUserAccessRequest = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ /** Body de PUT /tenants/{tenantId}/users/{cognitoSub}/api-access. */
16
+ class UpdateApiUserAccessRequest {
17
+ }
18
+ exports.UpdateApiUserAccessRequest = UpdateApiUserAccessRequest;
19
+ __decorate([
20
+ (0, class_transformer_1.Expose)(),
21
+ (0, class_validator_1.IsOptional)(),
22
+ (0, class_validator_1.IsArray)(),
23
+ (0, class_validator_1.ArrayNotEmpty)(),
24
+ (0, class_validator_1.IsString)({ each: true }),
25
+ __metadata("design:type", Array)
26
+ ], UpdateApiUserAccessRequest.prototype, "ipAllowlist", void 0);
27
+ __decorate([
28
+ (0, class_transformer_1.Expose)(),
29
+ (0, class_validator_1.IsOptional)(),
30
+ (0, class_validator_1.IsString)(),
31
+ (0, class_validator_1.MaxLength)(200),
32
+ __metadata("design:type", String)
33
+ ], UpdateApiUserAccessRequest.prototype, "technicalContact", void 0);
@@ -0,0 +1,5 @@
1
+ /** Tipo de cuenta de un usuario del pool. API entra por Bearer, sin 2FA. */
2
+ export declare enum AccountType {
3
+ HUMAN = "HUMAN",
4
+ API = "API"
5
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AccountType = void 0;
4
+ /** Tipo de cuenta de un usuario del pool. API entra por Bearer, sin 2FA. */
5
+ var AccountType;
6
+ (function (AccountType) {
7
+ AccountType["HUMAN"] = "HUMAN";
8
+ AccountType["API"] = "API";
9
+ })(AccountType || (exports.AccountType = AccountType = {}));
@@ -119,7 +119,8 @@ export declare enum Permission {
119
119
  PLATFORM_INTEGRATION_MANAGE = "platform.integration.manage",
120
120
  PLATFORM_INTEGRATION_KEY_ISSUE = "platform.integration.key.issue",
121
121
  PLATFORM_INTEGRATION_KEY_REVOKE = "platform.integration.key.revoke",
122
- TENANT_INTEGRATION_DIAGNOSTIC = "tenant.integration.diagnostic"
122
+ TENANT_INTEGRATION_DIAGNOSTIC = "tenant.integration.diagnostic",
123
+ TENANT_API_USER_MANAGE = "tenant.api_user.manage"
123
124
  }
124
125
  /**
125
126
  * Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
@@ -164,6 +164,8 @@ var Permission;
164
164
  // Por eso este es TENANT-scoped. Y por eso NO entra en el set de la guarda 1: no administra
165
165
  // nada, solo devuelve quién sos.
166
166
  Permission["TENANT_INTEGRATION_DIAGNOSTIC"] = "tenant.integration.diagnostic";
167
+ // Alta, rotación de secreto y edición de IPs de usuarios de API; se exige además de tenant.user.create.
168
+ Permission["TENANT_API_USER_MANAGE"] = "tenant.api_user.manage";
167
169
  })(Permission || (exports.Permission = Permission = {}));
168
170
  /**
169
171
  * Orden CANÓNICO y APPEND-ONLY de los permisos para el bitset del token.
@@ -283,6 +285,7 @@ exports.PERMISSION_BIT_ORDER = [
283
285
  Permission.PLATFORM_INTEGRATION_KEY_ISSUE,
284
286
  Permission.PLATFORM_INTEGRATION_KEY_REVOKE,
285
287
  Permission.TENANT_INTEGRATION_DIAGNOSTIC,
288
+ Permission.TENANT_API_USER_MANAGE,
286
289
  ];
287
290
  function djb2(input) {
288
291
  let h = 5381;
@@ -4,11 +4,13 @@
4
4
  * USER — persona autenticada con sesión de Cognito (cookie `session`).
5
5
  * INTEGRATION — credencial máquina-a-máquina de un socio externo (API key bearer). Su `cognitoSub`
6
6
  * tiene la forma `INT#<integrationId>` y NO viene de Cognito.
7
+ * API_USER — usuario de API del pool (token del client de API validado por el W5).
7
8
  *
8
9
  * NO confundir con `PrincipalIdentifierEnum` (EMAIL/PHONE), que es cómo se identifica un humano al
9
10
  * hacer login (DEC-RBAC-079). Este enum es el TIPO de principal, no cómo se identifica.
10
11
  */
11
12
  export declare enum PrincipalKind {
12
13
  USER = "USER",
13
- INTEGRATION = "INTEGRATION"
14
+ INTEGRATION = "INTEGRATION",
15
+ API_USER = "API_USER"
14
16
  }
@@ -7,6 +7,7 @@ exports.PrincipalKind = void 0;
7
7
  * USER — persona autenticada con sesión de Cognito (cookie `session`).
8
8
  * INTEGRATION — credencial máquina-a-máquina de un socio externo (API key bearer). Su `cognitoSub`
9
9
  * tiene la forma `INT#<integrationId>` y NO viene de Cognito.
10
+ * API_USER — usuario de API del pool (token del client de API validado por el W5).
10
11
  *
11
12
  * NO confundir con `PrincipalIdentifierEnum` (EMAIL/PHONE), que es cómo se identifica un humano al
12
13
  * hacer login (DEC-RBAC-079). Este enum es el TIPO de principal, no cómo se identifica.
@@ -15,4 +16,5 @@ var PrincipalKind;
15
16
  (function (PrincipalKind) {
16
17
  PrincipalKind["USER"] = "USER";
17
18
  PrincipalKind["INTEGRATION"] = "INTEGRATION";
19
+ PrincipalKind["API_USER"] = "API_USER";
18
20
  })(PrincipalKind || (exports.PrincipalKind = PrincipalKind = {}));
@@ -3,6 +3,7 @@ export { PermissionScope } from './enums/PermissionScope';
3
3
  export { PermissionCategory } from './enums/PermissionCategory';
4
4
  export { PrincipalIdentifierEnum } from './enums/PrincipalIdentifierEnum';
5
5
  export { PrincipalKind } from './enums/PrincipalKind';
6
+ export { AccountType } from './enums/AccountType';
6
7
  export type { AuthContext } from './dtos/AuthContext';
7
8
  export type { RoleAssignmentInfo } from './dtos/RoleAssignmentInfo';
8
9
  export type { PermissionMeta } from './dtos/PermissionMeta';
@@ -86,3 +87,10 @@ export * from './dtos/RevokeTenantRoleRequest';
86
87
  export type { RevokeTenantRoleResponse } from './dtos/RevokeTenantRoleResponse';
87
88
  export * from './dtos/TenantUsersBySubsRequest';
88
89
  export type { TenantUserBySubItem, TenantUsersBySubsResponse } from './dtos/TenantUsersBySubsResponse';
90
+ export * from './apiUser/ApiLoginRequest';
91
+ export * from './apiUser/ApiLoginResponse';
92
+ export * from './apiUser/CreateApiUserRequest';
93
+ export * from './apiUser/CreateApiUserResponse';
94
+ export * from './apiUser/RotateApiUserSecretResponse';
95
+ export * from './apiUser/UpdateApiUserAccessRequest';
96
+ export * from './apiUser/ApiUserWhoamiResponse';
@@ -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.UserFieldType = exports.scopeRankOrder = exports.tableSuffixForLevel = exports.levelsOf = exports.TENANT_TYPES = exports.TenantType = exports.AuthorizeDenyReason = exports.PrincipalKind = exports.PrincipalIdentifierEnum = 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.AccountType = exports.PrincipalKind = exports.PrincipalIdentifierEnum = 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; } });
@@ -41,6 +41,8 @@ Object.defineProperty(exports, "PrincipalIdentifierEnum", { enumerable: true, ge
41
41
  // que es cómo se identifica un humano al hacer login.
42
42
  var PrincipalKind_1 = require("./enums/PrincipalKind");
43
43
  Object.defineProperty(exports, "PrincipalKind", { enumerable: true, get: function () { return PrincipalKind_1.PrincipalKind; } });
44
+ var AccountType_1 = require("./enums/AccountType");
45
+ Object.defineProperty(exports, "AccountType", { enumerable: true, get: function () { return AccountType_1.AccountType; } });
44
46
  // Fase 1 — Custom Auth Challenge (Email OTP + TOTP) + MFA self-service.
45
47
  // Class values (no type-only) — los DTOs llevan decoradores class-validator y se hidratan con plainToInstance en runtime.
46
48
  __exportStar(require("./enums/MfaMethodEnum"), exports);
@@ -127,3 +129,11 @@ __exportStar(require("./dtos/AssignTenantRoleRequest"), exports);
127
129
  __exportStar(require("./dtos/RevokeTenantRoleRequest"), exports);
128
130
  // Batch privado de usuarios del tenant por cognitoSub (hub de miembros de group-business).
129
131
  __exportStar(require("./dtos/TenantUsersBySubsRequest"), exports);
132
+ // Usuarios de API: login por Bearer, alta, rotación de secreto y diagnóstico del W5.
133
+ __exportStar(require("./apiUser/ApiLoginRequest"), exports);
134
+ __exportStar(require("./apiUser/ApiLoginResponse"), exports);
135
+ __exportStar(require("./apiUser/CreateApiUserRequest"), exports);
136
+ __exportStar(require("./apiUser/CreateApiUserResponse"), exports);
137
+ __exportStar(require("./apiUser/RotateApiUserSecretResponse"), exports);
138
+ __exportStar(require("./apiUser/UpdateApiUserAccessRequest"), exports);
139
+ __exportStar(require("./apiUser/ApiUserWhoamiResponse"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.487.0",
3
+ "version": "3.488.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -1,22 +1,32 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsArray, IsBoolean, IsNumber, IsOptional, IsString } from 'class-validator';
2
+ import { IsArray, IsBoolean, IsIn, IsNumber, IsOptional, IsString } from 'class-validator';
3
+
4
+ /** Flujos de autenticación que Cognito admite en un app client. */
5
+ export const COGNITO_EXPLICIT_AUTH_FLOWS: readonly string[] = [
6
+ 'ALLOW_ADMIN_USER_PASSWORD_AUTH',
7
+ 'ALLOW_CUSTOM_AUTH',
8
+ 'ALLOW_USER_PASSWORD_AUTH',
9
+ 'ALLOW_USER_SRP_AUTH',
10
+ 'ALLOW_REFRESH_TOKEN_AUTH',
11
+ 'ALLOW_USER_AUTH',
12
+ ];
13
+
14
+ /** Unidades de vigencia de token; el conector aplica una sola a los tres tokens. */
15
+ export const COGNITO_TOKEN_VALIDITY_UNITS: readonly string[] = ['seconds', 'minutes', 'hours', 'days'];
3
16
 
4
17
  /**
5
- * Config del único App Client del pool nuevo creado por POST /pools.
6
- *
7
- * NO expone `generateSecret` — el connector hardcodea `GenerateSecret: false`
8
- * en el SDK call (BFF pattern: rbac llama al connector server-to-server vía
9
- * api-invoker en VPC, sin SPA-to-Cognito directo que requiera client secret).
10
- * Decisión arquitectónica A21 del connector. Si aparece consumer B2B/M2M con
11
- * flow `client_credentials`, evaluar con líder + bump major del connector.
18
+ * Config de un app client (el del pool nuevo de POST /pools o uno extra de POST /pools/{id}/clients).
19
+ * Sin `generateSecret`: el conector fija GenerateSecret false (A21).
12
20
  */
13
21
  export class AppClientConfig {
14
22
  @Expose() @IsOptional() @IsString() clientName?: string;
15
- @Expose() @IsArray() @IsString({ each: true }) explicitAuthFlows!: string[];
16
- @Expose() @IsOptional() @IsString() tokenValidityUnits?: string;
23
+ @Expose() @IsArray() @IsIn(COGNITO_EXPLICIT_AUTH_FLOWS, { each: true }) explicitAuthFlows!: string[];
24
+ @Expose() @IsOptional() @IsIn(COGNITO_TOKEN_VALIDITY_UNITS) tokenValidityUnits?: string;
17
25
  @Expose() @IsOptional() @IsNumber() accessTokenValidity?: number;
18
26
  @Expose() @IsOptional() @IsNumber() idTokenValidity?: number;
19
27
  @Expose() @IsOptional() @IsNumber() refreshTokenValidity?: number;
20
28
  @Expose() @IsOptional() @IsBoolean() preventUserExistenceErrors?: boolean;
21
29
  @Expose() @IsOptional() @IsBoolean() enableTokenRevocation?: boolean;
30
+ /** Atributos que el usuario puede escribir con su propio token. Ausente ⇒ todos (default de Cognito). */
31
+ @Expose() @IsOptional() @IsArray() @IsString({ each: true }) writeAttributes?: string[];
22
32
  }
@@ -0,0 +1,9 @@
1
+ import { Expose, Type } from 'class-transformer';
2
+ import { IsNotEmpty, IsString, ValidateNested } from 'class-validator';
3
+ import { AppClientConfig } from './AppClientConfig';
4
+
5
+ /** Body de POST /pools/{userPoolId}/clients: un app client extra sobre un pool existente. */
6
+ export class CreatePoolClientRequest {
7
+ @Expose() @IsString() @IsNotEmpty() region!: string;
8
+ @Expose() @ValidateNested() @Type(() => AppClientConfig) appClientConfig!: AppClientConfig;
9
+ }
@@ -0,0 +1,4 @@
1
+ /** Respuesta de POST /pools/{userPoolId}/clients. Sin secret: el client nace con GenerateSecret false. */
2
+ export class CreatePoolClientResponse {
3
+ appClientId!: string;
4
+ }
@@ -27,4 +27,6 @@ export class CreateUserRequest {
27
27
  @Expose() @IsString() @IsNotEmpty() tenantId!: string;
28
28
  @Expose() @IsOptional() @IsString() temporaryPassword?: string;
29
29
  @Expose() @IsOptional() @IsBoolean() suppressInvitationEmail?: boolean;
30
+ /** Ausente ⇒ true. false crea el identificador primario sin verificar (usuario de API). */
31
+ @Expose() @IsOptional() @IsBoolean() primaryIdentifierVerified?: boolean;
30
32
  }
@@ -49,6 +49,8 @@ export * from './dtos/AppClientConfig';
49
49
  export * from './dtos/CreatePoolRequest';
50
50
  export * from './dtos/CreatePoolResponse';
51
51
  export * from './dtos/DeletePoolRequest';
52
+ export * from './dtos/CreatePoolClientRequest';
53
+ export * from './dtos/CreatePoolClientResponse';
52
54
 
53
55
  // Introspección de token (POST /auth/introspect) — consumido por el platform-rbac-business.
54
56
  export * from './enums/IntrospectFailReason';
@@ -0,0 +1,9 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { IsNotEmpty, IsString } from 'class-validator';
3
+
4
+ /** Body de POST /auth/api/login. clientId es el sub del usuario de API y clientSecret su secreto. */
5
+ export class ApiLoginRequest {
6
+ @Expose() @IsString() @IsNotEmpty() clientId!: string;
7
+ @Expose() @IsString() @IsNotEmpty() clientSecret!: string;
8
+ @Expose() @IsString() @IsNotEmpty() tenantId!: string;
9
+ }
@@ -0,0 +1,6 @@
1
+ /** Respuesta 200 del login de API: solo el access token, nunca el refresh. */
2
+ export class ApiLoginResponse {
3
+ accessToken!: string;
4
+ expiresIn!: number;
5
+ tokenType!: 'Bearer';
6
+ }
@@ -0,0 +1,7 @@
1
+ /** Diagnóstico del W5 para usuarios de API: el principal ya resuelto por el adapter. */
2
+ export class ApiUserWhoamiResponse {
3
+ principalType!: 'API_USER';
4
+ principalId!: string;
5
+ tenantId!: string;
6
+ permissions!: string[];
7
+ }
@@ -0,0 +1,11 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { ArrayNotEmpty, IsArray, IsIn, IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3
+ import { AccountType } from '../enums/AccountType';
4
+
5
+ /** Alta de un usuario de API por POST /tenants/{tenantId}/users con accountType API. */
6
+ export class CreateApiUserRequest {
7
+ @Expose() @IsIn([AccountType.API]) accountType!: AccountType;
8
+ @Expose() @IsString() @IsNotEmpty() @MaxLength(120) displayName!: string;
9
+ @Expose() @IsOptional() @IsString() @MaxLength(200) technicalContact?: string;
10
+ @Expose() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) ipAllowlist!: string[];
11
+ }
@@ -0,0 +1,10 @@
1
+ import type { AccountType } from '../enums/AccountType';
2
+
3
+ /** Credenciales del usuario de API recién creado. El secreto sale UNA sola vez. */
4
+ export class CreateApiUserResponse {
5
+ cognitoSub!: string;
6
+ clientId!: string;
7
+ clientSecret!: string;
8
+ status!: 'ACTIVE';
9
+ accountType!: AccountType;
10
+ }
@@ -0,0 +1,5 @@
1
+ /** Secreto nuevo tras rotar. El anterior y los tokens vivos dejan de servir. */
2
+ export class RotateApiUserSecretResponse {
3
+ clientId!: string;
4
+ clientSecret!: string;
5
+ }
@@ -0,0 +1,8 @@
1
+ import { Expose } from 'class-transformer';
2
+ import { ArrayNotEmpty, IsArray, IsOptional, IsString, MaxLength } from 'class-validator';
3
+
4
+ /** Body de PUT /tenants/{tenantId}/users/{cognitoSub}/api-access. */
5
+ export class UpdateApiUserAccessRequest {
6
+ @Expose() @IsOptional() @IsArray() @ArrayNotEmpty() @IsString({ each: true }) ipAllowlist?: string[];
7
+ @Expose() @IsOptional() @IsString() @MaxLength(200) technicalContact?: string;
8
+ }
@@ -0,0 +1,5 @@
1
+ /** Tipo de cuenta de un usuario del pool. API entra por Bearer, sin 2FA. */
2
+ export enum AccountType {
3
+ HUMAN = 'HUMAN',
4
+ API = 'API',
5
+ }
@@ -163,6 +163,8 @@ export enum Permission {
163
163
  // Por eso este es TENANT-scoped. Y por eso NO entra en el set de la guarda 1: no administra
164
164
  // nada, solo devuelve quién sos.
165
165
  TENANT_INTEGRATION_DIAGNOSTIC = 'tenant.integration.diagnostic',
166
+ // Alta, rotación de secreto y edición de IPs de usuarios de API; se exige además de tenant.user.create.
167
+ TENANT_API_USER_MANAGE = 'tenant.api_user.manage',
166
168
  }
167
169
 
168
170
  /**
@@ -283,6 +285,7 @@ export const PERMISSION_BIT_ORDER: readonly Permission[] = [
283
285
  Permission.PLATFORM_INTEGRATION_KEY_ISSUE,
284
286
  Permission.PLATFORM_INTEGRATION_KEY_REVOKE,
285
287
  Permission.TENANT_INTEGRATION_DIAGNOSTIC,
288
+ Permission.TENANT_API_USER_MANAGE,
286
289
  ] as const;
287
290
 
288
291
  function djb2(input: string): number {
@@ -4,6 +4,7 @@
4
4
  * USER — persona autenticada con sesión de Cognito (cookie `session`).
5
5
  * INTEGRATION — credencial máquina-a-máquina de un socio externo (API key bearer). Su `cognitoSub`
6
6
  * tiene la forma `INT#<integrationId>` y NO viene de Cognito.
7
+ * API_USER — usuario de API del pool (token del client de API validado por el W5).
7
8
  *
8
9
  * NO confundir con `PrincipalIdentifierEnum` (EMAIL/PHONE), que es cómo se identifica un humano al
9
10
  * hacer login (DEC-RBAC-079). Este enum es el TIPO de principal, no cómo se identifica.
@@ -11,4 +12,5 @@
11
12
  export enum PrincipalKind {
12
13
  USER = 'USER',
13
14
  INTEGRATION = 'INTEGRATION',
15
+ API_USER = 'API_USER',
14
16
  }
@@ -22,6 +22,7 @@ export { PrincipalIdentifierEnum } from './enums/PrincipalIdentifierEnum';
22
22
  // DEC-RBAC-120: TIPO de principal (humano vs credencial M2M). No confundir con el de arriba,
23
23
  // que es cómo se identifica un humano al hacer login.
24
24
  export { PrincipalKind } from './enums/PrincipalKind';
25
+ export { AccountType } from './enums/AccountType';
25
26
 
26
27
  export type { AuthContext } from './dtos/AuthContext';
27
28
  export type { RoleAssignmentInfo } from './dtos/RoleAssignmentInfo';
@@ -182,3 +183,12 @@ export type { RevokeTenantRoleResponse } from './dtos/RevokeTenantRoleResponse';
182
183
  // Batch privado de usuarios del tenant por cognitoSub (hub de miembros de group-business).
183
184
  export * from './dtos/TenantUsersBySubsRequest';
184
185
  export type { TenantUserBySubItem, TenantUsersBySubsResponse } from './dtos/TenantUsersBySubsResponse';
186
+
187
+ // Usuarios de API: login por Bearer, alta, rotación de secreto y diagnóstico del W5.
188
+ export * from './apiUser/ApiLoginRequest';
189
+ export * from './apiUser/ApiLoginResponse';
190
+ export * from './apiUser/CreateApiUserRequest';
191
+ export * from './apiUser/CreateApiUserResponse';
192
+ export * from './apiUser/RotateApiUserSecretResponse';
193
+ export * from './apiUser/UpdateApiUserAccessRequest';
194
+ export * from './apiUser/ApiUserWhoamiResponse';