@fiado/type-kit 3.59.0 → 3.60.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.
@@ -1,53 +1,53 @@
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', () => {
7
- const valid = {
8
- userPoolId: 'us-east-1_abc123',
9
- region: 'us-east-1',
10
- email: 'user@acme.com',
11
- tenantId: 'somosfiado',
12
- };
13
-
14
- it('valida happy path con tenantId slug (0 errores)', async () => {
15
- const dto = plainToInstance(CreateUserRequest, valid);
16
- const errors = await validate(dto);
17
- expect(errors).toEqual([]);
18
- });
19
-
20
- it('acepta un tenantId slug con guiones (acme-mx)', async () => {
21
- const dto = plainToInstance(CreateUserRequest, { ...valid, tenantId: 'acme-mx' });
22
- const errors = await validate(dto);
23
- expect(errors.some(e => e.property === 'tenantId')).toBe(false);
24
- });
25
-
26
- it('acepta un tenantId con forma de UUID (sigue siendo string válido)', async () => {
27
- const dto = plainToInstance(CreateUserRequest, {
28
- ...valid,
29
- tenantId: '11111111-1111-1111-1111-111111111111',
30
- });
31
- const errors = await validate(dto);
32
- expect(errors.some(e => e.property === 'tenantId')).toBe(false);
33
- });
34
-
35
- it('falla si tenantId está vacío', async () => {
36
- const dto = plainToInstance(CreateUserRequest, { ...valid, tenantId: '' });
37
- const errors = await validate(dto);
38
- expect(errors.some(e => e.property === 'tenantId')).toBe(true);
39
- });
40
-
41
- it('preserva los campos opcionales legítimos', async () => {
42
- const dto = plainToInstance(CreateUserRequest, {
43
- ...valid,
44
- displayName: 'Usuario Demo',
45
- temporaryPassword: 'Temp1234!',
46
- suppressInvitationEmail: true,
47
- });
48
- const errors = await validate(dto);
49
- expect(errors).toEqual([]);
50
- expect(dto.displayName).toBe('Usuario Demo');
51
- expect(dto.suppressInvitationEmail).toBe(true);
52
- });
53
- });
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', () => {
7
+ const valid = {
8
+ userPoolId: 'us-east-1_abc123',
9
+ region: 'us-east-1',
10
+ email: 'user@acme.com',
11
+ tenantId: 'somosfiado',
12
+ };
13
+
14
+ it('valida happy path con tenantId slug (0 errores)', async () => {
15
+ const dto = plainToInstance(CreateUserRequest, valid);
16
+ const errors = await validate(dto);
17
+ expect(errors).toEqual([]);
18
+ });
19
+
20
+ it('acepta un tenantId slug con guiones (acme-mx)', async () => {
21
+ const dto = plainToInstance(CreateUserRequest, { ...valid, tenantId: 'acme-mx' });
22
+ const errors = await validate(dto);
23
+ expect(errors.some(e => e.property === 'tenantId')).toBe(false);
24
+ });
25
+
26
+ it('acepta un tenantId con forma de UUID (sigue siendo string válido)', async () => {
27
+ const dto = plainToInstance(CreateUserRequest, {
28
+ ...valid,
29
+ tenantId: '11111111-1111-1111-1111-111111111111',
30
+ });
31
+ const errors = await validate(dto);
32
+ expect(errors.some(e => e.property === 'tenantId')).toBe(false);
33
+ });
34
+
35
+ it('falla si tenantId está vacío', async () => {
36
+ const dto = plainToInstance(CreateUserRequest, { ...valid, tenantId: '' });
37
+ const errors = await validate(dto);
38
+ expect(errors.some(e => e.property === 'tenantId')).toBe(true);
39
+ });
40
+
41
+ it('preserva los campos opcionales legítimos', async () => {
42
+ const dto = plainToInstance(CreateUserRequest, {
43
+ ...valid,
44
+ displayName: 'Usuario Demo',
45
+ temporaryPassword: 'Temp1234!',
46
+ suppressInvitationEmail: true,
47
+ });
48
+ const errors = await validate(dto);
49
+ expect(errors).toEqual([]);
50
+ expect(dto.displayName).toBe('Usuario Demo');
51
+ expect(dto.suppressInvitationEmail).toBe(true);
52
+ });
53
+ });
@@ -1,32 +1,32 @@
1
- import 'reflect-metadata';
2
- import { plainToInstance } from 'class-transformer';
3
- import { validate } from 'class-validator';
4
- import { VerifyPasswordResponse } from '../../../../src/cognitoBackofficeConnector/dtos/VerifyPasswordResponse';
5
- import { CognitoChallengeType } from '../../../../src/cognitoBackofficeConnector/enums/CognitoChallengeType';
6
-
7
- describe('VerifyPasswordResponse', () => {
8
- it('solo valid (backward-compatible)', async () => {
9
- const dto = plainToInstance(VerifyPasswordResponse, { valid: true });
10
- expect(await validate(dto)).toEqual([]);
11
- });
12
-
13
- it('valid + challenge nativo NEW_PASSWORD_REQUIRED + session', async () => {
14
- const dto = plainToInstance(VerifyPasswordResponse, {
15
- valid: true,
16
- challengeType: CognitoChallengeType.NEW_PASSWORD_REQUIRED,
17
- session: 'sess-123',
18
- challengeParameters: { USER_ID_FOR_SRP: 'sub' },
19
- });
20
- expect(await validate(dto)).toEqual([]);
21
- });
22
-
23
- it('falla si challengeType no es del enum', async () => {
24
- const dto = plainToInstance(VerifyPasswordResponse, { valid: true, challengeType: 'BOGUS' });
25
- expect((await validate(dto)).some(e => e.property === 'challengeType')).toBe(true);
26
- });
27
-
28
- it('falla si valid no es boolean', async () => {
29
- const dto = plainToInstance(VerifyPasswordResponse, { valid: 'yes' });
30
- expect((await validate(dto)).some(e => e.property === 'valid')).toBe(true);
31
- });
32
- });
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate } from 'class-validator';
4
+ import { VerifyPasswordResponse } from '../../../../src/cognitoBackofficeConnector/dtos/VerifyPasswordResponse';
5
+ import { CognitoChallengeType } from '../../../../src/cognitoBackofficeConnector/enums/CognitoChallengeType';
6
+
7
+ describe('VerifyPasswordResponse', () => {
8
+ it('solo valid (backward-compatible)', async () => {
9
+ const dto = plainToInstance(VerifyPasswordResponse, { valid: true });
10
+ expect(await validate(dto)).toEqual([]);
11
+ });
12
+
13
+ it('valid + challenge nativo NEW_PASSWORD_REQUIRED + session', async () => {
14
+ const dto = plainToInstance(VerifyPasswordResponse, {
15
+ valid: true,
16
+ challengeType: CognitoChallengeType.NEW_PASSWORD_REQUIRED,
17
+ session: 'sess-123',
18
+ challengeParameters: { USER_ID_FOR_SRP: 'sub' },
19
+ });
20
+ expect(await validate(dto)).toEqual([]);
21
+ });
22
+
23
+ it('falla si challengeType no es del enum', async () => {
24
+ const dto = plainToInstance(VerifyPasswordResponse, { valid: true, challengeType: 'BOGUS' });
25
+ expect((await validate(dto)).some(e => e.property === 'challengeType')).toBe(true);
26
+ });
27
+
28
+ it('falla si valid no es boolean', async () => {
29
+ const dto = plainToInstance(VerifyPasswordResponse, { valid: 'yes' });
30
+ expect((await validate(dto)).some(e => e.property === 'valid')).toBe(true);
31
+ });
32
+ });
@@ -17,7 +17,8 @@ class VerifyOtpRequest {
17
17
  exports.VerifyOtpRequest = VerifyOtpRequest;
18
18
  __decorate([
19
19
  (0, class_transformer_1.Expose)(),
20
- (0, class_validator_1.IsUUID)(),
20
+ (0, class_validator_1.IsString)(),
21
+ (0, class_validator_1.IsNotEmpty)(),
21
22
  __metadata("design:type", String)
22
23
  ], VerifyOtpRequest.prototype, "directoryId", void 0);
23
24
  __decorate([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.59.0",
3
+ "version": "3.60.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -1,24 +1,24 @@
1
- import { Expose } from 'class-transformer';
2
- import { IsBoolean, IsEnum, IsObject, IsOptional, IsString } from 'class-validator';
3
- import { CognitoChallengeType } from '../enums/CognitoChallengeType';
4
-
5
- /**
6
- * Respuesta de `POST /auth/verify-password`.
7
- *
8
- * `valid` es el único campo siempre presente (consumidores legacy hacen
9
- * `const { valid } = ...`). Los campos opcionales surfacean el challenge nativo
10
- * que `ADMIN_USER_PASSWORD_AUTH` devuelve sin throw: para un usuario en
11
- * `FORCE_CHANGE_PASSWORD`, Cognito responde `ChallengeName:'NEW_PASSWORD_REQUIRED'`
12
- * + `Session`, y el caller (rbac) los usa para emitir ese challenge nativo FUERA
13
- * de CUSTOM_AUTH en vez de arrancar el MFA (F-12). Backward-compatible: todos los
14
- * campos nuevos son opcionales.
15
- */
16
- export class VerifyPasswordResponse {
17
- @Expose() @IsBoolean() valid!: boolean;
18
-
19
- @Expose() @IsOptional() @IsEnum(CognitoChallengeType) challengeType?: CognitoChallengeType;
20
-
21
- @Expose() @IsOptional() @IsString() session?: string;
22
-
23
- @Expose() @IsOptional() @IsObject() challengeParameters?: Record<string, string>;
24
- }
1
+ import { Expose } from 'class-transformer';
2
+ import { IsBoolean, IsEnum, IsObject, IsOptional, IsString } from 'class-validator';
3
+ import { CognitoChallengeType } from '../enums/CognitoChallengeType';
4
+
5
+ /**
6
+ * Respuesta de `POST /auth/verify-password`.
7
+ *
8
+ * `valid` es el único campo siempre presente (consumidores legacy hacen
9
+ * `const { valid } = ...`). Los campos opcionales surfacean el challenge nativo
10
+ * que `ADMIN_USER_PASSWORD_AUTH` devuelve sin throw: para un usuario en
11
+ * `FORCE_CHANGE_PASSWORD`, Cognito responde `ChallengeName:'NEW_PASSWORD_REQUIRED'`
12
+ * + `Session`, y el caller (rbac) los usa para emitir ese challenge nativo FUERA
13
+ * de CUSTOM_AUTH en vez de arrancar el MFA (F-12). Backward-compatible: todos los
14
+ * campos nuevos son opcionales.
15
+ */
16
+ export class VerifyPasswordResponse {
17
+ @Expose() @IsBoolean() valid!: boolean;
18
+
19
+ @Expose() @IsOptional() @IsEnum(CognitoChallengeType) challengeType?: CognitoChallengeType;
20
+
21
+ @Expose() @IsOptional() @IsString() session?: string;
22
+
23
+ @Expose() @IsOptional() @IsObject() challengeParameters?: Record<string, string>;
24
+ }
@@ -1,8 +1,12 @@
1
1
  import { Expose } from 'class-transformer';
2
- import { IsNotEmpty, IsString, IsUUID } from 'class-validator';
2
+ import { IsNotEmpty, IsString } from 'class-validator';
3
3
 
4
4
  export class VerifyOtpRequest {
5
- @Expose() @IsUUID() directoryId!: string;
5
+ // directoryId NO se valida como @IsUUID: los cognitoSub de los pools backoffice son UUID v7
6
+ // (nibble de versión = 7), que class-validator @IsUUID() (v1-5) rechaza → el verify de OTP
7
+ // tiraba 400 "directoryId must be a UUID" para TODOS esos users. El SEND
8
+ // (NotificationQueueMessageRequestV2.directoryId) ya usa @IsString — esto lo deja consistente.
9
+ @Expose() @IsString() @IsNotEmpty() directoryId!: string;
6
10
  @Expose() @IsString() @IsNotEmpty() typeOfDirectoryId!: string;
7
11
  @Expose() @IsString() @IsNotEmpty() message!: string;
8
12
  }