Files
azuredatastudio/src/sql/parts/connection/connectionDialog/connectionWidget.ts

650 lines
25 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./media/sqlConnection';
import { Button } from 'sql/base/browser/ui/button/button';
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import * as DialogHelper from 'sql/base/browser/ui/modal/dialogHelper';
import { IConnectionComponentCallbacks } from 'sql/parts/connection/connectionDialog/connectionDialogService';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes';
import * as Constants from 'sql/parts/connection/common/constants';
import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { attachInputBoxStyler, attachButtonStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler';
import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import { ConnectionProfile } from '../common/connectionProfile';
import * as sqlops from 'sqlops';
import * as lifecycle from 'vs/base/common/lifecycle';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { localize } from 'vs/nls';
import * as DOM from 'vs/base/browser/dom';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import * as styler from 'vs/platform/theme/common/styler';
import { OS, OperatingSystem } from 'vs/base/common/platform';
import { Builder, $ } from 'vs/base/browser/builder';
import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
import { endsWith, startsWith } from 'vs/base/common/strings';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
export class ConnectionWidget {
private _builder: Builder;
private _serverGroupSelectBox: SelectBox;
private _previousGroupOption: string;
private _serverGroupOptions: IConnectionProfileGroup[];
private _connectionNameInputBox: InputBox;
private _serverNameInputBox: InputBox;
private _databaseNameInputBox: Dropdown;
private _userNameInputBox: InputBox;
private _passwordInputBox: InputBox;
private _password: string;
private _rememberPasswordCheckBox: Checkbox;
private _advancedButton: Button;
private _callbacks: IConnectionComponentCallbacks;
private _authTypeSelectBox: SelectBox;
private _toDispose: lifecycle.IDisposable[];
private _optionsMaps: { [optionType: number]: sqlops.ConnectionOption };
private _tableContainer: Builder;
private _focusedBeforeHandleOnConnection: HTMLElement;
private _providerName: string;
private _authTypeMap: { [providerName: string]: AuthenticationType[] } = {
[Constants.mssqlProviderName]: [new AuthenticationType(Constants.integrated, false), new AuthenticationType(Constants.sqlLogin, true)]
};
private _saveProfile: boolean;
private _databaseDropdownExpanded: boolean = false;
private _defaultDatabaseName: string = localize('defaultDatabaseOption', '<Default>');
private _loadingDatabaseName: string = localize('loadingDatabaseOption', 'Loading...');
private _serverGroupDisplayString: string = localize('serverGroup', 'Server group');
public DefaultServerGroup: IConnectionProfileGroup = {
id: '',
name: localize('defaultServerGroup', '<Default>'),
parentId: undefined,
color: undefined,
description: undefined,
};
private _addNewServerGroup = {
id: '',
name: localize('addNewServerGroup', 'Add new group...'),
parentId: undefined,
color: undefined,
description: undefined,
};
public NoneServerGroup: IConnectionProfileGroup = {
id: '',
name: localize('noneServerGroup', '<Do not save>'),
parentId: undefined,
color: undefined,
description: undefined,
};
constructor(options: sqlops.ConnectionOption[],
callbacks: IConnectionComponentCallbacks,
providerName: string,
@IThemeService private _themeService: IThemeService,
@IContextViewService private _contextViewService: IContextViewService,
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
@ICapabilitiesService private _capabilitiesService: ICapabilitiesService,
@IClipboardService private _clipboardService: IClipboardService,
@IConfigurationService private _configurationService: IConfigurationService
) {
this._callbacks = callbacks;
this._toDispose = [];
this._optionsMaps = {};
for (var i = 0; i < options.length; i++) {
var option = options[i];
this._optionsMaps[option.specialValueType] = option;
}
var authTypeOption = this._optionsMaps[ConnectionOptionSpecialType.authType];
if (authTypeOption) {
if (OS === OperatingSystem.Windows) {
authTypeOption.defaultValue = this.getAuthTypeDisplayName(Constants.integrated);
} else {
authTypeOption.defaultValue = this.getAuthTypeDisplayName(Constants.sqlLogin);
}
this._authTypeSelectBox = new SelectBox(authTypeOption.categoryValues.map(c => c.displayName), authTypeOption.defaultValue, this._contextViewService, undefined, { ariaLabel: authTypeOption.displayName });
}
this._providerName = providerName;
}
public createConnectionWidget(container: HTMLElement): void {
this._serverGroupOptions = [this.DefaultServerGroup];
this._serverGroupSelectBox = new SelectBox(this._serverGroupOptions.map(g => g.name), this.DefaultServerGroup.name, this._contextViewService, undefined, { ariaLabel: this._serverGroupDisplayString });
this._previousGroupOption = this._serverGroupSelectBox.value;
this._builder = $().div({ class: 'connection-table' }, (modelTableContent) => {
modelTableContent.element('table', { class: 'connection-table-content' }, (tableContainer) => {
this._tableContainer = tableContainer;
});
});
this.fillInConnectionForm();
this.registerListeners();
if (this._authTypeSelectBox) {
this.onAuthTypeSelected(this._authTypeSelectBox.value);
}
DOM.addDisposableListener(container, 'paste', e => {
this._handleClipboard();
});
DOM.append(container, this._builder.getHTMLElement());
}
private _handleClipboard(): void {
if (this._configurationService.getValue<boolean>('connection.parseClipboardForConnectionString')) {
let paste = this._clipboardService.readText();
this._connectionManagementService.buildConnectionInfo(paste, this._providerName).then(e => {
if (e) {
let profile = new ConnectionProfile(this._capabilitiesService, this._providerName);
profile.options = e.options;
if (profile.serverName) {
this.initDialog(profile);
}
}
});
}
}
private fillInConnectionForm(): void {
// Server name
let serverNameOption = this._optionsMaps[ConnectionOptionSpecialType.serverName];
let serverNameBuilder = DialogHelper.appendRow(this._tableContainer, serverNameOption.displayName, 'connection-label', 'connection-input');
this._serverNameInputBox = new InputBox(serverNameBuilder.getHTMLElement(), this._contextViewService, {
validationOptions: {
validation: (value: string) => {
if (!value) {
return ({ type: MessageType.ERROR, content: localize('connectionWidget.missingRequireField', '{0} is required.', serverNameOption.displayName) });
} else if (startsWith(value, ' ') || endsWith(value, ' ')) {
return ({ type: MessageType.WARNING, content: localize('connectionWidget.fieldWillBeTrimmed', '{0} will be trimmed.', serverNameOption.displayName) });
}
return undefined;
}
},
ariaLabel: serverNameOption.displayName
});
// Authentication type
if (this._optionsMaps[ConnectionOptionSpecialType.authType]) {
let authTypeBuilder = DialogHelper.appendRow(this._tableContainer, this._optionsMaps[ConnectionOptionSpecialType.authType].displayName, 'connection-label', 'connection-input');
DialogHelper.appendInputSelectBox(authTypeBuilder, this._authTypeSelectBox);
}
// Username
let self = this;
let userNameOption = this._optionsMaps[ConnectionOptionSpecialType.userName];
let userNameBuilder = DialogHelper.appendRow(this._tableContainer, userNameOption.displayName, 'connection-label', 'connection-input');
this._userNameInputBox = new InputBox(userNameBuilder.getHTMLElement(), this._contextViewService, {
validationOptions: {
validation: (value: string) => self.validateUsername(value, userNameOption.isRequired) ? ({ type: MessageType.ERROR, content: localize('connectionWidget.missingRequireField', '{0} is required.', userNameOption.displayName) }) : null
},
ariaLabel: userNameOption.displayName
});
// Password
let passwordOption = this._optionsMaps[ConnectionOptionSpecialType.password];
let passwordBuilder = DialogHelper.appendRow(this._tableContainer, passwordOption.displayName, 'connection-label', 'connection-input');
this._passwordInputBox = new InputBox(passwordBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: passwordOption.displayName });
this._passwordInputBox.inputElement.type = 'password';
this._password = '';
// Remember password
let rememberPasswordLabel = localize('rememberPassword', 'Remember password');
this._rememberPasswordCheckBox = this.appendCheckbox(this._tableContainer, rememberPasswordLabel, 'connection-checkbox', 'connection-input', false);
// Database
let databaseOption = this._optionsMaps[ConnectionOptionSpecialType.databaseName];
let databaseNameBuilder = DialogHelper.appendRow(this._tableContainer, databaseOption.displayName, 'connection-label', 'connection-input');
this._databaseNameInputBox = new Dropdown(databaseNameBuilder.getHTMLElement(), this._contextViewService, this._themeService, {
values: [this._defaultDatabaseName, this._loadingDatabaseName],
strictSelection: false,
placeholder: this._defaultDatabaseName,
maxHeight: 125,
ariaLabel: databaseOption.displayName,
actionLabel: localize('connectionWidget.toggleDatabaseNameDropdown', 'Select Database Toggle Dropdown')
});
// Server group
let serverGroupBuilder = DialogHelper.appendRow(this._tableContainer, this._serverGroupDisplayString, 'connection-label', 'connection-input');
DialogHelper.appendInputSelectBox(serverGroupBuilder, this._serverGroupSelectBox);
// Connection name
let connectionNameOption = this._optionsMaps[ConnectionOptionSpecialType.connectionName];
let connectionNameBuilder = DialogHelper.appendRow(this._tableContainer, connectionNameOption.displayName, 'connection-label', 'connection-input');
this._connectionNameInputBox = new InputBox(connectionNameBuilder.getHTMLElement(), this._contextViewService, { ariaLabel: connectionNameOption.displayName });
let AdvancedLabel = localize('advanced', 'Advanced...');
this._advancedButton = this.createAdvancedButton(this._tableContainer, AdvancedLabel);
}
private validateUsername(value: string, isOptionRequired: boolean): boolean {
let currentAuthType = this._authTypeSelectBox ? this.getMatchingAuthType(this._authTypeSelectBox.value) : undefined;
if (!currentAuthType || currentAuthType.showUsernameAndPassword) {
if (!value && isOptionRequired) {
return true;
}
}
return false;
}
private createAdvancedButton(container: Builder, title: string): Button {
let button;
container.element('tr', {}, (rowContainer) => {
rowContainer.element('td');
rowContainer.element('td', { align: 'right' }, (cellContainer) => {
cellContainer.div({ class: 'advanced-button' }, (divContainer) => {
button = new Button(divContainer);
button.label = title;
button.onDidClick(() => {
//open advanced page
this._callbacks.onAdvancedProperties();
});
});
});
});
return button;
}
private appendCheckbox(container: Builder, label: string, checkboxClass: string, cellContainerClass: string, isChecked: boolean): Checkbox {
let checkbox: Checkbox;
container.element('tr', {}, (rowContainer) => {
rowContainer.element('td');
rowContainer.element('td', { class: cellContainerClass }, (inputCellContainer) => {
checkbox = new Checkbox(inputCellContainer.getHTMLElement(), { label, checked: isChecked, ariaLabel: label });
});
});
return checkbox;
}
private registerListeners(): void {
// Theme styler
this._toDispose.push(attachInputBoxStyler(this._serverNameInputBox, this._themeService));
this._toDispose.push(attachEditableDropdownStyler(this._databaseNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._connectionNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._userNameInputBox, this._themeService));
this._toDispose.push(attachInputBoxStyler(this._passwordInputBox, this._themeService));
this._toDispose.push(styler.attachSelectBoxStyler(this._serverGroupSelectBox, this._themeService));
this._toDispose.push(attachButtonStyler(this._advancedButton, this._themeService));
if (this._authTypeSelectBox) {
// Theme styler
this._toDispose.push(styler.attachSelectBoxStyler(this._authTypeSelectBox, this._themeService));
this._toDispose.push(this._authTypeSelectBox.onDidSelect(selectedAuthType => {
this.onAuthTypeSelected(selectedAuthType.selected);
this.setConnectButton();
}));
}
this._toDispose.push(this._serverGroupSelectBox.onDidSelect(selectedGroup => {
this.onGroupSelected(selectedGroup.selected);
}));
this._toDispose.push(this._serverNameInputBox.onDidChange(serverName => {
this.serverNameChanged(serverName);
}));
this._toDispose.push(this._userNameInputBox.onDidChange(userName => {
this.setConnectButton();
}));
this._toDispose.push(this._passwordInputBox.onDidChange(passwordInput => {
this._password = passwordInput;
}));
this._toDispose.push(this._databaseNameInputBox.onFocus(() => {
this._databaseDropdownExpanded = true;
if (this.serverName) {
this._databaseNameInputBox.values = [this._loadingDatabaseName];
this._callbacks.onFetchDatabases(this.serverName, this.authenticationType, this.userName, this._password).then(databases => {
if (databases) {
this._databaseNameInputBox.values = databases.sort((a, b) => a.localeCompare(b));
} else {
this._databaseNameInputBox.values = [this._defaultDatabaseName];
}
}).catch(() => {
this._databaseNameInputBox.values = [this._defaultDatabaseName];
});
} else {
this._databaseNameInputBox.values = [this._defaultDatabaseName];
}
}));
this._toDispose.push(this._databaseNameInputBox.onValueChange(s => {
if (s === this._defaultDatabaseName || s === this._loadingDatabaseName) {
this._databaseNameInputBox.value = '';
} else {
this._databaseNameInputBox.value = s;
}
}));
}
private onGroupSelected(selectedGroup: string) {
if (selectedGroup === this._addNewServerGroup.name) {
// Select previous non-AddGroup option in case AddServerGroup dialog is cancelled
this._serverGroupSelectBox.selectWithOptionName(this._previousGroupOption);
this._callbacks.onCreateNewServerGroup();
} else {
this._previousGroupOption = selectedGroup;
}
}
private setConnectButton(): void {
let showUsernameAndPassword: boolean = true;
if (this.authType) {
showUsernameAndPassword = this.authType.showUsernameAndPassword;
}
showUsernameAndPassword ? this._callbacks.onSetConnectButton(!!this.serverName && !!this.userName) :
this._callbacks.onSetConnectButton(!!this.serverName);
}
private onAuthTypeSelected(selectedAuthType: string) {
let currentAuthType = this.getMatchingAuthType(selectedAuthType);
if (!currentAuthType.showUsernameAndPassword) {
this._userNameInputBox.disable();
this._passwordInputBox.disable();
this._userNameInputBox.hideMessage();
this._passwordInputBox.hideMessage();
this._userNameInputBox.value = '';
this._passwordInputBox.value = '';
this._password = '';
this._rememberPasswordCheckBox.checked = false;
this._rememberPasswordCheckBox.enabled = false;
} else {
this._userNameInputBox.enable();
this._passwordInputBox.enable();
this._rememberPasswordCheckBox.enabled = true;
}
}
private serverNameChanged(serverName: string) {
this.setConnectButton();
if (serverName.toLocaleLowerCase().includes('database.windows.net')) {
this._callbacks.onSetAzureTimeOut();
}
}
public focusOnAdvancedButton() {
this._advancedButton.focus();
}
public focusOnServerGroup() {
this._serverGroupSelectBox.focus();
}
public updateServerGroup(connectionGroups: IConnectionProfileGroup[], groupName?: string) {
this._serverGroupOptions = connectionGroups;
this._serverGroupOptions.push(this._addNewServerGroup);
this._serverGroupSelectBox.setOptions(this._serverGroupOptions.map(g => g.name));
if (groupName) {
this._serverGroupSelectBox.selectWithOptionName(groupName);
this._previousGroupOption = this._serverGroupSelectBox.value;
}
}
public initDialog(connectionInfo: IConnectionProfile): void {
this.fillInConnectionInputs(connectionInfo);
}
public focusOnOpen(): void {
this._handleClipboard();
this._serverNameInputBox.focus();
this.focusPasswordIfNeeded();
this.clearValidationMessages();
}
private clearValidationMessages(): void {
this._serverNameInputBox.hideMessage();
this._userNameInputBox.hideMessage();
}
private getModelValue(value: string): string {
return value ? value : '';
}
public fillInConnectionInputs(connectionInfo: IConnectionProfile) {
if (connectionInfo) {
this._serverNameInputBox.value = this.getModelValue(connectionInfo.serverName);
this._databaseNameInputBox.value = this.getModelValue(connectionInfo.databaseName);
this._connectionNameInputBox.value = this.getModelValue(connectionInfo.connectionName);
this._userNameInputBox.value = this.getModelValue(connectionInfo.userName);
this._passwordInputBox.value = connectionInfo.password ? Constants.passwordChars : '';
this._password = this.getModelValue(connectionInfo.password);
this._saveProfile = connectionInfo.saveProfile;
let groupName: string;
if (this._saveProfile) {
if (!connectionInfo.groupFullName) {
groupName = this.DefaultServerGroup.name;
} else {
groupName = connectionInfo.groupFullName.replace('root/', '');
}
} else {
groupName = this.NoneServerGroup.name;
}
this._serverGroupSelectBox.selectWithOptionName(groupName);
this._previousGroupOption = this._serverGroupSelectBox.value;
// To handle the empty password case
if (this.getModelValue(connectionInfo.password) === '') {
this._rememberPasswordCheckBox.checked = false;
} else {
this._rememberPasswordCheckBox.checked = connectionInfo.savePassword;
}
if (connectionInfo.authenticationType !== null && connectionInfo.authenticationType !== undefined) {
var authTypeDisplayName = this.getAuthTypeDisplayName(connectionInfo.authenticationType);
this._authTypeSelectBox.selectWithOptionName(authTypeDisplayName);
}
if (this._authTypeSelectBox) {
this.onAuthTypeSelected(this._authTypeSelectBox.value);
}
// Disable connect button if -
// 1. Authentication type is SQL Login and no username is provided
// 2. No server name is provided
this.setConnectButton();
this.focusPasswordIfNeeded();
}
}
private getAuthTypeDisplayName(authTypeName: string) {
var displayName: string;
var authTypeOption = this._optionsMaps[ConnectionOptionSpecialType.authType];
if (authTypeOption) {
authTypeOption.categoryValues.forEach(c => {
if (c.name === authTypeName) {
displayName = c.displayName;
}
});
}
return displayName;
}
private getAuthTypeName(authTypeDisplayName: string) {
var authTypeName: string;
var authTypeOption = this._optionsMaps[ConnectionOptionSpecialType.authType];
authTypeOption.categoryValues.forEach(c => {
if (c.displayName === authTypeDisplayName) {
authTypeName = c.name;
}
});
return authTypeName;
}
public handleOnConnecting(): void {
this._focusedBeforeHandleOnConnection = <HTMLElement>document.activeElement;
this._advancedButton.enabled = false;
this._serverGroupSelectBox.disable();
this._serverNameInputBox.disable();
this._databaseNameInputBox.enabled = false;
this._userNameInputBox.disable();
this._passwordInputBox.disable();
this._connectionNameInputBox.disable();
this._rememberPasswordCheckBox.enabled = false;
if (this._authTypeSelectBox) {
this._authTypeSelectBox.disable();
}
}
public handleResetConnection(): void {
this._advancedButton.enabled = true;
this._serverGroupSelectBox.enable();
this._serverNameInputBox.enable();
this._connectionNameInputBox.enable();
this._databaseNameInputBox.enabled = true;
let currentAuthType: AuthenticationType = undefined;
if (this._authTypeSelectBox) {
this._authTypeSelectBox.enable();
currentAuthType = this.getMatchingAuthType(this._authTypeSelectBox.value);
}
if (!currentAuthType || currentAuthType.showUsernameAndPassword) {
this._userNameInputBox.enable();
this._passwordInputBox.enable();
this._rememberPasswordCheckBox.enabled = true;
}
if (this._focusedBeforeHandleOnConnection) {
this._focusedBeforeHandleOnConnection.focus();
}
}
public get connectionName(): string {
return this._connectionNameInputBox.value;
}
public get serverName(): string {
return this._serverNameInputBox.value;
}
public get databaseName(): string {
return this._databaseNameInputBox.value;
}
public get userName(): string {
return this._userNameInputBox.value;
}
public get password(): string {
return this._password;
}
public get authenticationType(): string {
return this._authTypeSelectBox ? this.getAuthTypeName(this._authTypeSelectBox.value) : undefined;
}
private validateInputs(): boolean {
let isFocused = false;
let validateServerName = this._serverNameInputBox.validate();
if (!validateServerName) {
this._serverNameInputBox.focus();
isFocused = true;
}
let validateUserName = this._userNameInputBox.validate();
if (!validateUserName && !isFocused) {
this._userNameInputBox.focus();
isFocused = true;
}
let validatePassword = this._passwordInputBox.validate();
if (!validatePassword && !isFocused) {
this._passwordInputBox.focus();
isFocused = true;
}
return validateServerName && validateUserName && validatePassword;
}
public connect(model: IConnectionProfile): boolean {
let validInputs = this.validateInputs();
if (validInputs) {
model.connectionName = this.connectionName;
model.serverName = this.serverName;
model.databaseName = this.databaseName;
model.userName = this.userName;
model.password = this.password;
model.authenticationType = this.authenticationType;
model.savePassword = this._rememberPasswordCheckBox.checked;
if (this._serverGroupSelectBox.value === this.DefaultServerGroup.name) {
model.groupFullName = '';
model.saveProfile = true;
model.groupId = this.findGroupId(model.groupFullName);
} else if (this._serverGroupSelectBox.value === this.NoneServerGroup.name) {
model.groupFullName = '';
model.saveProfile = false;
} else if (this._serverGroupSelectBox.value !== this._addNewServerGroup.name) {
model.groupFullName = this._serverGroupSelectBox.value;
model.saveProfile = true;
model.groupId = this.findGroupId(model.groupFullName);
}
}
return validInputs;
}
private findGroupId(groupFullName: string): string {
let group: IConnectionProfileGroup;
if (ConnectionProfileGroup.isRoot(groupFullName)) {
group = this._serverGroupOptions.find(g => ConnectionProfileGroup.isRoot(g.name));
if (group === undefined) {
group = this._serverGroupOptions.find(g => g.name === this.DefaultServerGroup.name);
}
} else {
group = this._serverGroupOptions.find(g => g.name === groupFullName);
}
return group ? group.id : undefined;
}
public dispose(): void {
this._toDispose = lifecycle.dispose(this._toDispose);
}
private getMatchingAuthType(displayName: string): AuthenticationType {
const authType = this._authTypeMap[this._providerName];
return authType ? authType.find(authType => this.getAuthTypeDisplayName(authType.name) === displayName) : undefined;
}
public closeDatabaseDropdown(): void {
this._databaseNameInputBox.blur();
}
public get databaseDropdownExpanded(): boolean {
return this._databaseDropdownExpanded;
}
public set databaseDropdownExpanded(val: boolean) {
this._databaseDropdownExpanded = val;
}
private get authType(): AuthenticationType {
let authDisplayName: string = this.getAuthTypeDisplayName(this.authenticationType);
return this.getMatchingAuthType(authDisplayName);
}
private focusPasswordIfNeeded(): void {
if (this.authType && this.authType.showUsernameAndPassword && this.userName && !this.password) {
this._passwordInputBox.focus();
}
}
}
class AuthenticationType {
public name: string;
public showUsernameAndPassword: boolean;
constructor(name: string, showUsernameAndPassword: boolean) {
this.name = name;
this.showUsernameAndPassword = showUsernameAndPassword;
}
}