credential for recent connections (#17152)
* credential for recent connections * fix linting error * pr comments * pr comments * pr comments * lint error * lint error * final linting error fix
This commit is contained in:
Родитель
c96daae34a
Коммит
b47f09874c
|
@ -554,6 +554,12 @@
|
|||
<trans-unit id="nodeErrorMessage">
|
||||
<source xml:lang="en">Parent node was not TreeNodeInfo.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="deleteCredentialError">
|
||||
<source xml:lang="en">Failed to delete credential with id: {0}. {1}</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="msgClearedRecentConnectionsWithErrors">
|
||||
<source xml:lang="en">The recent connections list has been cleared but there were errors while deleting some associated credentials. View the errors in the MSSQL output channel.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
@ -97,11 +97,9 @@ export default class ConnectionManager {
|
|||
private _accountStore?: AccountStore) {
|
||||
this._statusView = statusView;
|
||||
this._connections = {};
|
||||
this._connectionCredentialsToServerInfoMap =
|
||||
new Map<IConnectionInfo, ConnectionContracts.ServerInfo>();
|
||||
this._connectionCredentialsToServerInfoMap = new Map<IConnectionInfo, ConnectionContracts.ServerInfo>();
|
||||
this._uriToConnectionPromiseMap = new Map<string, Deferred<boolean>>();
|
||||
|
||||
|
||||
if (!this.client) {
|
||||
this.client = SqlToolsServerClient.instance;
|
||||
}
|
||||
|
@ -314,6 +312,13 @@ export default class ConnectionManager {
|
|||
let mruConnection: IConnectionInfo = <any>{};
|
||||
|
||||
if (Utils.isNotEmpty(result.connectionId)) {
|
||||
// Use the original connection information to save the MRU connection.
|
||||
// for connections that a database is not provided, the database information will be updated
|
||||
// to the default database name, if we use the new information as the MRU connection,
|
||||
// the connection information will be different from the saved connections (saved connection's database property is empty).
|
||||
// When deleting the saved connection, we won't be able to find its corresponding recent connection,
|
||||
// and the saved connection credentials will become orphaned.
|
||||
mruConnection = Utils.deepClone(connection.credentials);
|
||||
// Convert to credentials if it's a connection string based connection
|
||||
if (connection.credentials.connectionString) {
|
||||
connection.credentials = this.populateCredentialsFromConnectionString(connection.credentials, result.connectionSummary);
|
||||
|
@ -328,7 +333,6 @@ export default class ConnectionManager {
|
|||
newCredentials.database = result.connectionSummary.databaseName;
|
||||
}
|
||||
self.handleConnectionSuccess(fileUri, connection, newCredentials, result);
|
||||
mruConnection = connection.credentials;
|
||||
const promise = self._uriToConnectionPromiseMap.get(result.ownerUri);
|
||||
if (promise) {
|
||||
promise.resolve(true);
|
||||
|
@ -464,9 +468,10 @@ export default class ConnectionManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Clear the recently used connections list in the connection store
|
||||
* Clear the recently used connections list in the connection store.
|
||||
* @returns a boolean value indicating whether the credentials were deleted successfully.
|
||||
*/
|
||||
public clearRecentConnectionsList(): Promise<void> {
|
||||
public clearRecentConnectionsList(): Promise<boolean> {
|
||||
return this.connectionStore.clearRecentlyUsed();
|
||||
}
|
||||
|
||||
|
|
|
@ -292,14 +292,24 @@ export class ConnectionStore {
|
|||
|
||||
/**
|
||||
* Clear all recently used connections from the MRU list.
|
||||
* @returns a boolean value indicating whether the credentials were deleted successfully.
|
||||
*/
|
||||
public async clearRecentlyUsed(): Promise<void> {
|
||||
// Update the MRU list to be empty
|
||||
try {
|
||||
await this._context.globalState.update(Constants.configRecentConnections, []);
|
||||
} catch (error) {
|
||||
Promise.reject(error);
|
||||
public async clearRecentlyUsed(): Promise<boolean> {
|
||||
// Get all recent connection profiles and delete the associated credentials.
|
||||
const mruList = this.getRecentlyUsedConnections();
|
||||
let deleteCredentialSuccess = true;
|
||||
for (const connection of mruList) {
|
||||
const credentialId = ConnectionStore.formatCredentialId(connection.server, connection.database, connection.user, ConnectionStore.CRED_MRU_USER);
|
||||
try {
|
||||
await this._credentialStore.deleteCredential(credentialId);
|
||||
} catch (err) {
|
||||
deleteCredentialSuccess = false;
|
||||
Utils.logToOutputChannel(Utils.formatString(LocalizedConstants.deleteCredentialError, credentialId, err));
|
||||
}
|
||||
}
|
||||
// Update the MRU list to be empty
|
||||
await this._context.globalState.update(Constants.configRecentConnections, []);
|
||||
return deleteCredentialSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -494,3 +494,25 @@ export function generateQueryUri(scheme = 'vscode-mssql-adhoc'): vscode.Uri {
|
|||
authority: `Query${uriIndex++}`
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* deep clone the object. Copied from vscode: https://github.com/microsoft/vscode/blob/main/src/vs/base/common/objects.ts#L8
|
||||
*/
|
||||
export function deepClone<T>(obj: T): T {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return obj;
|
||||
}
|
||||
if (obj instanceof RegExp) {
|
||||
// See https://github.com/microsoft/TypeScript/issues/10990
|
||||
return obj as any;
|
||||
}
|
||||
const result: any = Array.isArray(obj) ? [] : {};
|
||||
Object.keys(<any>obj).forEach((key: string) => {
|
||||
if ((<any>obj)[key] && typeof (<any>obj)[key] === 'object') {
|
||||
result[key] = deepClone((<any>obj)[key]);
|
||||
} else {
|
||||
result[key] = (<any>obj)[key];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -389,8 +389,12 @@ export class ConnectionUI {
|
|||
case ManageProfileTask.ClearRecentlyUsed:
|
||||
self.promptToClearRecentConnectionsList().then(result => {
|
||||
if (result) {
|
||||
self.connectionManager.clearRecentConnectionsList().then(() => {
|
||||
self.vscodeWrapper.showInformationMessage(LocalizedConstants.msgClearedRecentConnections);
|
||||
self.connectionManager.clearRecentConnectionsList().then((credentialsDeleted) => {
|
||||
if (credentialsDeleted) {
|
||||
self.vscodeWrapper.showInformationMessage(LocalizedConstants.msgClearedRecentConnections);
|
||||
} else {
|
||||
self.vscodeWrapper.showWarningMessage(LocalizedConstants.msgClearedRecentConnectionsWithErrors);
|
||||
}
|
||||
resolve(true);
|
||||
});
|
||||
} else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче