2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { Sequencer } from '../../../../base/common/async.js';
7
>
import { decodeBase64, encodeBase64, VSBuffer } from '../../../../base/common/buffer.js';
8
>
import { Lazy } from '../../../../base/common/lazy.js';
9
>
import { Disposable } from '../../../../base/common/lifecycle.js';
10
>
import { isEmptyObject } from '../../../../base/common/types.js';
11
>
import { ILogService } from '../../../../platform/log/common/log.js';
12
>
import { ISecretStorageService } from '../../../../platform/secrets/common/secrets.js';
13
>
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';
14
>
import { IResolvedValue } from '../../../services/configurationResolver/common/configurationResolverExpression.js';
15
>
16
>
const MCP_ENCRYPTION_KEY_NAME = 'mcpEncryptionKey';
17
>
const MCP_ENCRYPTION_KEY_ALGORITHM = 'AES-GCM';
18
>
const MCP_ENCRYPTION_KEY_LEN = 256;
19
>
const MCP_ENCRYPTION_IV_LENGTH = 12; // 96 bits
20
>
const MCP_DATA_STORED_VERSION = 1;
21
>
const MCP_DATA_STORED_KEY = 'mcpInputs';
22
>
23
>
interface IStoredData {
24
>
version: number;
25
>
values: Record<string, IResolvedValue>;
26
>
secrets?: { value: string; iv: string }; // base64, encrypted
27
>
}
28
>
29
>
interface IHydratedData extends IStoredData {
30
>
unsealedSecrets?: Record<string, IResolvedValue>;
31
>
}
32
>
33
>
export class McpRegistryInputStorage extends Disposable {
34
>
private static secretSequencer = new Sequencer();
35
>
private readonly _secretsSealerSequencer = new Sequencer();
36
>
37
>
private readonly _getEncryptionKey = new Lazy(() => {
38
return McpRegistryInputStorage.secretSequencer.queue(async () => {
39
const existing = await this._secretStorageService.get(MCP_ENCRYPTION_KEY_NAME);