From 72f7e8de5241b504da9306ac0b02f33c087606e7 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Mon, 19 Oct 2020 10:52:17 -0700 Subject: [PATCH] add password validation regex (#12976) --- extensions/asde-deployment/package.json | 10 ++++++++-- extensions/asde-deployment/package.nls.json | 1 + .../src/ui/modelViewUtils.ts | 19 +++++++------------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/extensions/asde-deployment/package.json b/extensions/asde-deployment/package.json index b8e9639a87..a995d37393 100644 --- a/extensions/asde-deployment/package.json +++ b/extensions/asde-deployment/package.json @@ -28,7 +28,10 @@ "light": "./images/sqldb_edge.svg", "dark": "./images/sqldb_edge_inverse.svg" }, - "tags": ["Hybrid", "SQL Server"], + "tags": [ + "Hybrid", + "SQL Server" + ], "options": [ { "name": "type", @@ -338,7 +341,10 @@ "type": "password", "confirmationRequired": true, "confirmationLabel": "%vm_password_confirm%", - "required": true + "required": true, + "textValidationRequired": true, + "textValidationRegex": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[\\W_])[A-Za-z\\d\\W_]{12,123}$", + "textValidationDescription": "%vm_password_validation_error_message%" } ] }, diff --git a/extensions/asde-deployment/package.nls.json b/extensions/asde-deployment/package.nls.json index 4c4823fda3..184df6e136 100644 --- a/extensions/asde-deployment/package.nls.json +++ b/extensions/asde-deployment/package.nls.json @@ -33,6 +33,7 @@ "vm_admin": "VM admin username", "vm_password": "VM admin password", "vm_password_confirm": "Confirm VM admin password", + "vm_password_validation_error_message": "VM password must be 12 to 123 characters in length and consists of upper case characters, lower case characters, numbers and special characters.", "package_path": "Package file", "package_path_description": "Path of the SQL Server package file(dacpac, bacpac) or compressed package file.", "azure-info-section-title": "Azure information", diff --git a/extensions/resource-deployment/src/ui/modelViewUtils.ts b/extensions/resource-deployment/src/ui/modelViewUtils.ts index 22bc670b1b..e7d947de4c 100644 --- a/extensions/resource-deployment/src/ui/modelViewUtils.ts +++ b/extensions/resource-deployment/src/ui/modelViewUtils.ts @@ -119,6 +119,7 @@ interface ContextBase { } export function createTextInput(view: azdata.ModelView, inputInfo: { + type?: azdata.InputBoxInputType, defaultValue?: string, ariaLabel: string, required?: boolean, @@ -131,7 +132,7 @@ export function createTextInput(view: azdata.ModelView, inputInfo: { return view.modelBuilder.inputBox().withProperties({ value: inputInfo.defaultValue, ariaLabel: inputInfo.ariaLabel, - inputType: 'text', + inputType: inputInfo.type || 'text', required: inputInfo.required, placeHolder: inputInfo.placeHolder, width: inputInfo.width, @@ -538,9 +539,11 @@ function processNumberField(context: FieldContext): void { } function processTextField(context: FieldContext): void { + const isPasswordField = context.fieldInfo.type === FieldType.Password || context.fieldInfo.type === FieldType.SQLPassword; let validationRegex: RegExp | undefined = context.fieldInfo.textValidationRequired ? new RegExp(context.fieldInfo.textValidationRegex!) : undefined; const label = createLabel(context.view, { text: context.fieldInfo.label, description: context.fieldInfo.description, required: context.fieldInfo.required, width: context.fieldInfo.labelWidth, cssStyles: context.fieldInfo.labelCSSStyles }); const input = createTextInput(context.view, { + type: isPasswordField ? 'password' : 'text', defaultValue: context.fieldInfo.defaultValue, ariaLabel: context.fieldInfo.label, required: context.fieldInfo.required, @@ -550,7 +553,7 @@ function processTextField(context: FieldContext): void { validationRegex: validationRegex, validationErrorMessage: context.fieldInfo.textValidationDescription }); - context.onNewInputComponentCreated(context.fieldInfo.variableName!, { component: input }); + context.onNewInputComponentCreated(context.fieldInfo.variableName!, { component: input, isPassword: isPasswordField }); addLabelInputPairToContainer(context.view, context.components, label, input, context.fieldInfo); if (context.fieldInfo.textValidationRequired) { @@ -573,16 +576,8 @@ function processTextField(context: FieldContext): void { } function processPasswordField(context: FieldContext): void { - const passwordLabel = createLabel(context.view, { text: context.fieldInfo.label, description: context.fieldInfo.description, required: context.fieldInfo.required, width: context.fieldInfo.labelWidth, cssStyles: context.fieldInfo.labelCSSStyles }); - const passwordInput = context.view.modelBuilder.inputBox().withProperties({ - ariaLabel: context.fieldInfo.label, - inputType: 'password', - required: context.fieldInfo.required, - placeHolder: context.fieldInfo.placeHolder, - width: context.fieldInfo.inputWidth - }).component(); - context.onNewInputComponentCreated(context.fieldInfo.variableName!, { component: passwordInput, isPassword: true }); - addLabelInputPairToContainer(context.view, context.components, passwordLabel, passwordInput, context.fieldInfo); + processTextField(context); + const passwordInput = context.inputComponents[context.fieldInfo.variableName!].component as azdata.InputBoxComponent; if (context.fieldInfo.type === FieldType.SQLPassword) { const invalidPasswordMessage = getInvalidSQLPasswordMessage(context.fieldInfo.label);