/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { ICredentialsService, ICredentialsProvider, ICredentialsChangeEvent } from 'vs/workbench/services/credentials/common/credentials'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; export class BrowserCredentialsService extends Disposable implements ICredentialsService { declare readonly _serviceBrand: undefined; private _onDidChangePassword = this._register(new Emitter()); readonly onDidChangePassword = this._onDidChangePassword.event; private credentialsProvider: ICredentialsProvider; constructor(@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService) { super(); if (environmentService.options && environmentService.options.credentialsProvider) { this.credentialsProvider = environmentService.options.credentialsProvider; } else { this.credentialsProvider = new InMemoryCredentialsProvider(); } } getPassword(service: string, account: string): Promise { return this.credentialsProvider.getPassword(service, account); } async setPassword(service: string, account: string, password: string): Promise { await this.credentialsProvider.setPassword(service, account, password); this._onDidChangePassword.fire({ service, account }); } deletePassword(service: string, account: string): Promise { const didDelete = this.credentialsProvider.deletePassword(service, account); if (didDelete) { this._onDidChangePassword.fire({ service, account }); } return didDelete; } findPassword(service: string): Promise { return this.credentialsProvider.findPassword(service); } findCredentials(service: string): Promise> { return this.credentialsProvider.findCredentials(service); } } interface ICredential { service: string; account: string; password: string; } class InMemoryCredentialsProvider implements ICredentialsProvider { private credentials: ICredential[] = []; async getPassword(service: string, account: string): Promise { const credential = this.doFindPassword(service, account); return credential ? credential.password : null; } async setPassword(service: string, account: string, password: string): Promise { this.deletePassword(service, account); this.credentials.push({ service, account, password }); } async deletePassword(service: string, account: string): Promise { const credential = this.doFindPassword(service, account); if (credential) { this.credentials = this.credentials.splice(this.credentials.indexOf(credential), 1); } return !!credential; } async findPassword(service: string): Promise { const credential = this.doFindPassword(service); return credential ? credential.password : null; } private doFindPassword(service: string, account?: string): ICredential | undefined { return this.credentials.find(credential => credential.service === service && (typeof account !== 'string' || credential.account === account)); } async findCredentials(service: string): Promise> { return this.credentials .filter(credential => credential.service === service) .map(({ account, password }) => ({ account, password })); } } registerSingleton(ICredentialsService, BrowserCredentialsService, true);