From b2811e07ceabebb2b6329e53feacd6bc2cf194f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Thu, 7 Nov 2024 15:23:01 -0500 Subject: [PATCH] [PM-14198] zero minimums when the character category is disabled (#11906) --- .../core/src/policies/constraints.ts | 2 ++ ...ynamic-password-policy-constraints.spec.ts | 26 ++++--------------- .../dynamic-password-policy-constraints.ts | 6 ++--- 3 files changed, 10 insertions(+), 24 deletions(-) diff --git a/libs/tools/generator/core/src/policies/constraints.ts b/libs/tools/generator/core/src/policies/constraints.ts index 6071b57048..d320329938 100644 --- a/libs/tools/generator/core/src/policies/constraints.ts +++ b/libs/tools/generator/core/src/policies/constraints.ts @@ -2,6 +2,7 @@ import { Constraint } from "@bitwarden/common/tools/types"; import { sum } from "../util"; +const Zero: Constraint = { min: 0, max: 0 }; const AtLeastOne: Constraint = { min: 1 }; const RequiresTrue: Constraint = { requiredValue: true }; @@ -159,6 +160,7 @@ export { enforceConstant, readonlyTrueWhen, fitLength, + Zero, AtLeastOne, RequiresTrue, }; diff --git a/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts b/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts index 96f590f8ed..d05d75ffb7 100644 --- a/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts +++ b/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.spec.ts @@ -1,6 +1,6 @@ import { DefaultPasswordBoundaries, DefaultPasswordGenerationOptions, Policies } from "../data"; -import { AtLeastOne } from "./constraints"; +import { AtLeastOne, Zero } from "./constraints"; import { DynamicPasswordPolicyConstraints } from "./dynamic-password-policy-constraints"; describe("DynamicPasswordPolicyConstraints", () => { @@ -207,7 +207,7 @@ describe("DynamicPasswordPolicyConstraints", () => { expect(calibrated.constraints.minNumber).toEqual(dynamic.constraints.minNumber); }); - it("disables the minNumber constraint when the state's number flag is false", () => { + it("outputs the zero constraint when the state's number flag is false", () => { const dynamic = new DynamicPasswordPolicyConstraints(Policies.Password.disabledValue); const state = { ...DefaultPasswordGenerationOptions, @@ -216,7 +216,7 @@ describe("DynamicPasswordPolicyConstraints", () => { const calibrated = dynamic.calibrate(state); - expect(calibrated.constraints.minNumber).toBeUndefined(); + expect(calibrated.constraints.minNumber).toEqual(Zero); }); it("outputs the minSpecial constraint when the state's special flag is true", () => { @@ -231,7 +231,7 @@ describe("DynamicPasswordPolicyConstraints", () => { expect(calibrated.constraints.minSpecial).toEqual(dynamic.constraints.minSpecial); }); - it("disables the minSpecial constraint when the state's special flag is false", () => { + it("outputs the zero constraint when the state's special flag is false", () => { const dynamic = new DynamicPasswordPolicyConstraints(Policies.Password.disabledValue); const state = { ...DefaultPasswordGenerationOptions, @@ -240,23 +240,7 @@ describe("DynamicPasswordPolicyConstraints", () => { const calibrated = dynamic.calibrate(state); - expect(calibrated.constraints.minSpecial).toBeUndefined(); - }); - - it("copies the minimum length constraint", () => { - const dynamic = new DynamicPasswordPolicyConstraints(Policies.Password.disabledValue); - - const calibrated = dynamic.calibrate(DefaultPasswordGenerationOptions); - - expect(calibrated.constraints.minSpecial).toBeUndefined(); - }); - - it("overrides the minimum length constraint when it is less than the sum of the state's minimums", () => { - const dynamic = new DynamicPasswordPolicyConstraints(Policies.Password.disabledValue); - - const calibrated = dynamic.calibrate(DefaultPasswordGenerationOptions); - - expect(calibrated.constraints.minSpecial).toBeUndefined(); + expect(calibrated.constraints.minSpecial).toEqual(Zero); }); }); }); diff --git a/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.ts b/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.ts index daff988254..7fe7606188 100644 --- a/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.ts +++ b/libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.ts @@ -7,7 +7,7 @@ import { import { DefaultPasswordBoundaries } from "../data"; import { PasswordGeneratorPolicy, PasswordGeneratorSettings } from "../types"; -import { atLeast, atLeastSum, maybe, readonlyTrueWhen, AtLeastOne } from "./constraints"; +import { atLeast, atLeastSum, maybe, readonlyTrueWhen, AtLeastOne, Zero } from "./constraints"; import { PasswordPolicyConstraints } from "./password-policy-constraints"; /** Creates state constraints by blending policy and password settings. */ @@ -68,8 +68,8 @@ export class DynamicPasswordPolicyConstraints ...this.constraints, minLowercase: maybe(lowercase, this.constraints.minLowercase ?? AtLeastOne), minUppercase: maybe(uppercase, this.constraints.minUppercase ?? AtLeastOne), - minNumber: maybe(number, this.constraints.minNumber), - minSpecial: maybe(special, this.constraints.minSpecial), + minNumber: maybe(number, this.constraints.minNumber) ?? Zero, + minSpecial: maybe(special, this.constraints.minSpecial) ?? Zero, }; // lower bound of length must always at least fit its sub-lengths